diff --git a/.gitignore b/.gitignore
index 6e053a5..7077ab2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -184,7 +184,6 @@
 /gyp-mac-tool
 /infra/.recipe_deps
 /internal_gyp
-/ios/build/util/CANARY_VERSION
 /ios/third_party/earl_grey/src
 /ios/third_party/fishhook/src
 /ios/third_party/gcdwebserver/src
diff --git a/BUILD.gn b/BUILD.gn
index 6fa5f29..933f4ed 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -340,6 +340,7 @@
   if (is_chromeos) {
     deps += [
       "//chromeos:chromeos_unittests",
+      "//ui/arc:ui_arc_unittests",
       "//ui/chromeos:ui_chromeos_unittests",
     ]
   }
diff --git a/DEPS b/DEPS
index 4d2a752..ccf11aa 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': '236640872fa8cad105273055fdcf6829d5c025a1',
+  'skia_revision': '4984c3c95f18eda44492a2126c9958e447f2cca8',
   # 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': 'f72954451b6d4d92c7d583eefe79abce29a993c8',
+  'v8_revision': '3c3b9fbb1ffa2c7d3f48cadc2f66568d3e125e0e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -51,7 +51,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': 'b5abec33708fe1edf13d335c847b98318cd0bb13',
+  'angle_revision': 'bd382711c33bf4e419f0ad011feaff603907d2ae',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -110,7 +110,7 @@
 
 deps = {
   'src/breakpad/src':
-   Var('chromium_git') + '/breakpad/breakpad/src.git' + '@' + '7fef95a322beedaddcca627e1a88b54411f586da',
+   Var('chromium_git') + '/breakpad/breakpad/src.git' + '@' + '481608d284106df9400d447e95574799670cabaf',
 
   'src/buildtools':
    Var('chromium_git') + '/chromium/buildtools.git' + '@' +  Var('buildtools_revision'),
@@ -267,7 +267,7 @@
 
   'src/third_party/catapult':
     Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' +
-    'aa910ba5517667b17b5fca67aa5c5985d9d8247a',
+    '14c08ceb0eb454ac75638ca56a914801917a7b1d',
 
   'src/third_party/openh264/src':
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b37cda248234162033e3e11b0335f3131cdfe488',
@@ -650,13 +650,6 @@
                '-s', 'src/third_party/WebKit',
                '-o', 'src/build/util/LASTCHANGE.blink'],
   },
-  {
-    # Update CANARY_VERSION.
-    'name': 'ios_canary_version',
-    'pattern': '.',
-    'action': ['python', 'src/ios/build/util/canary_version.py',
-               '-o', 'src/ios/build/util/CANARY_VERSION'],
-  },
   # Pull GN binaries. This needs to be before running GYP below.
   {
     'name': 'gn_win',
diff --git a/android_webview/browser/deferred_gpu_command_service.cc b/android_webview/browser/deferred_gpu_command_service.cc
index d2a19f6..9021deb 100644
--- a/android_webview/browser/deferred_gpu_command_service.cc
+++ b/android_webview/browser/deferred_gpu_command_service.cc
@@ -12,6 +12,7 @@
 #include "base/synchronization/lock.h"
 #include "base/trace_event/trace_event.h"
 #include "content/public/browser/android/synchronous_compositor.h"
+#include "content/public/browser/gpu_utils.h"
 #include "content/public/common/content_switches.h"
 #include "gpu/command_buffer/service/framebuffer_completeness_cache.h"
 #include "gpu/command_buffer/service/gpu_preferences.h"
@@ -27,75 +28,6 @@
 base::LazyInstance<scoped_refptr<DeferredGpuCommandService> >
     g_service = LAZY_INSTANCE_INITIALIZER;
 
-bool GetSizeTFromSwitch(const base::CommandLine* command_line,
-                        const base::StringPiece& switch_string,
-                        size_t* value) {
-  if (!command_line->HasSwitch(switch_string))
-    return false;
-  std::string switch_value(command_line->GetSwitchValueASCII(switch_string));
-  return base::StringToSizeT(switch_value, value);
-}
-
-gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
-  // TODO(penghuang): share below code with content/gpu/gpu_child_thread.cc
-  // http://crbug.com/590825
-  DCHECK(base::CommandLine::InitializedForCurrentProcess());
-  const base::CommandLine* command_line =
-      base::CommandLine::ForCurrentProcess();
-  gpu::GpuPreferences gpu_preferences;
-  gpu_preferences.single_process =
-      command_line->HasSwitch(switches::kSingleProcess);
-  gpu_preferences.in_process_gpu =
-      command_line->HasSwitch(switches::kInProcessGPU);
-  gpu_preferences.ui_prioritize_in_gpu_process =
-      command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess);
-  gpu_preferences.compile_shader_always_succeeds =
-      command_line->HasSwitch(switches::kCompileShaderAlwaysSucceeds);
-  gpu_preferences.disable_gl_error_limit =
-    command_line->HasSwitch(switches::kDisableGLErrorLimit);
-  gpu_preferences.disable_glsl_translator =
-    command_line->HasSwitch(switches::kDisableGLSLTranslator);
-  gpu_preferences.disable_gpu_driver_bug_workarounds =
-    command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds);
-  gpu_preferences.disable_shader_name_hashing =
-    command_line->HasSwitch(switches::kDisableShaderNameHashing);
-  gpu_preferences.enable_gpu_command_logging =
-    command_line->HasSwitch(switches::kEnableGPUCommandLogging);
-  gpu_preferences.enable_gpu_debugging =
-    command_line->HasSwitch(switches::kEnableGPUDebugging);
-  gpu_preferences.enable_gpu_service_logging_gpu =
-    command_line->HasSwitch(switches::kEnableGPUServiceLoggingGPU);
-  gpu_preferences.disable_gpu_program_cache =
-    command_line->HasSwitch(switches::kDisableGpuProgramCache);
-  gpu_preferences.enforce_gl_minimums =
-    command_line->HasSwitch(switches::kEnforceGLMinimums);
-  if (GetSizeTFromSwitch(command_line, switches::kForceGpuMemAvailableMb,
-                         &gpu_preferences.force_gpu_mem_available)) {
-    gpu_preferences.force_gpu_mem_available *= 1024 * 1024;
-  }
-  if (GetSizeTFromSwitch(command_line, switches::kGpuProgramCacheSizeKb,
-                         &gpu_preferences.gpu_program_cache_size)) {
-    gpu_preferences.gpu_program_cache_size *= 1024;
-  }
-  gpu_preferences.enable_share_group_async_texture_upload =
-    command_line->HasSwitch(switches::kEnableShareGroupAsyncTextureUpload);
-  gpu_preferences.enable_subscribe_uniform_extension =
-    command_line->HasSwitch(switches::kEnableSubscribeUniformExtension);
-  gpu_preferences.enable_threaded_texture_mailboxes =
-    command_line->HasSwitch(switches::kEnableThreadedTextureMailboxes);
-  gpu_preferences.gl_shader_interm_output =
-    command_line->HasSwitch(switches::kGLShaderIntermOutput);
-  gpu_preferences.emulate_shader_precision =
-    command_line->HasSwitch(switches::kEmulateShaderPrecision);
-  gpu_preferences.enable_gpu_service_logging =
-      command_line->HasSwitch(switches::kEnableGPUServiceLogging);
-  gpu_preferences.enable_gpu_service_tracing =
-      command_line->HasSwitch(switches::kEnableGPUServiceTracing);
-  gpu_preferences.enable_unsafe_es3_apis =
-    command_line->HasSwitch(switches::kEnableUnsafeES3APIs);
-  return gpu_preferences;
-}
-
 }  // namespace
 
 base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl;
@@ -140,7 +72,8 @@
 }
 
 DeferredGpuCommandService::DeferredGpuCommandService()
-    : gpu::InProcessCommandBuffer::Service(GetGpuPreferencesFromCommandLine()),
+    : gpu::InProcessCommandBuffer::Service(
+          content::GetGpuPreferencesFromCommandLine()),
       sync_point_manager_(new gpu::SyncPointManager(true)) {
 }
 
diff --git a/ash/mus/BUILD.gn b/ash/mus/BUILD.gn
index c6e9c9c..4ca9bac2 100644
--- a/ash/mus/BUILD.gn
+++ b/ash/mus/BUILD.gn
@@ -76,11 +76,11 @@
   ]
   deps = [
     ":lib",
-    ":manifest",
     "//mojo/shell/public/cpp",
   ]
 
   data_deps = [
+    ":manifest",
     "//components/mus",
   ]
 }
diff --git a/ash/wm/immersive_fullscreen_controller.cc b/ash/wm/immersive_fullscreen_controller.cc
index 7d0a8515..54773ae7 100644
--- a/ash/wm/immersive_fullscreen_controller.cc
+++ b/ash/wm/immersive_fullscreen_controller.cc
@@ -24,6 +24,7 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/screen.h"
 #include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 #include "ui/wm/core/transient_window_manager.h"
@@ -63,16 +64,40 @@
 const int kHeightOfDeadRegionAboveTopContainer = 10;
 
 // Returns the BubbleDelegateView corresponding to |maybe_bubble| if
-// |maybe_bubble| is a bubble.
+// |maybe_bubble| is a bubble. TODO(estade): remove this when all bubbles are
+// BubbleDialogDelegateViews, or create a common interface for the two bubble
+// types.
 views::BubbleDelegateView* AsBubbleDelegate(aura::Window* maybe_bubble) {
   if (!maybe_bubble)
-    return NULL;
+    return nullptr;
   views::Widget* widget = views::Widget::GetWidgetForNativeView(maybe_bubble);
   if (!widget)
-    return NULL;
+    return nullptr;
   return widget->widget_delegate()->AsBubbleDelegate();
 }
 
+// Returns the BubbleDialogDelegateView corresponding to |maybe_bubble| if
+// |maybe_bubble| is a bubble.
+views::BubbleDialogDelegateView* AsBubbleDialogDelegate(
+    aura::Window* maybe_bubble) {
+  if (!maybe_bubble)
+    return nullptr;
+  views::Widget* widget = views::Widget::GetWidgetForNativeView(maybe_bubble);
+  if (!widget)
+    return nullptr;
+  return widget->widget_delegate()->AsBubbleDialogDelegate();
+}
+
+views::View* GetAnchorView(aura::Window* maybe_bubble) {
+  views::BubbleDelegateView* bubble = AsBubbleDelegate(maybe_bubble);
+  if (bubble)
+    return bubble->GetAnchorView();
+
+  views::BubbleDialogDelegateView* bubble_dialog =
+      AsBubbleDialogDelegate(maybe_bubble);
+  return bubble_dialog ? bubble_dialog->GetAnchorView() : nullptr;
+}
+
 // Returns true if |maybe_transient| is a transient child of |toplevel|.
 bool IsWindowTransientChildOf(aura::Window* maybe_transient,
                               aura::Window* toplevel) {
@@ -128,11 +153,11 @@
 // so that bubbles which are not activatable and bubbles which do not close
 // upon deactivation also keep the top-of-window views revealed for the
 // duration of their visibility.
-class ImmersiveFullscreenController::BubbleManager
+class ImmersiveFullscreenController::BubbleObserver
     : public aura::WindowObserver {
  public:
-  explicit BubbleManager(ImmersiveFullscreenController* controller);
-  ~BubbleManager() override;
+  explicit BubbleObserver(ImmersiveFullscreenController* controller);
+  ~BubbleObserver() override;
 
   // Start / stop observing changes to |bubble|'s visibility.
   void StartObserving(aura::Window* bubble);
@@ -154,22 +179,21 @@
   // |bubbles_| is visible.
   scoped_ptr<ImmersiveRevealedLock> revealed_lock_;
 
-  DISALLOW_COPY_AND_ASSIGN(BubbleManager);
+  DISALLOW_COPY_AND_ASSIGN(BubbleObserver);
 };
 
-ImmersiveFullscreenController::BubbleManager::BubbleManager(
+ImmersiveFullscreenController::BubbleObserver::BubbleObserver(
     ImmersiveFullscreenController* controller)
-    : controller_(controller) {
-}
+    : controller_(controller) {}
 
-ImmersiveFullscreenController::BubbleManager::~BubbleManager() {
+ImmersiveFullscreenController::BubbleObserver::~BubbleObserver() {
   for (std::set<aura::Window*>::const_iterator it = bubbles_.begin();
        it != bubbles_.end(); ++it) {
     (*it)->RemoveObserver(this);
   }
 }
 
-void ImmersiveFullscreenController::BubbleManager::StartObserving(
+void ImmersiveFullscreenController::BubbleObserver::StartObserving(
     aura::Window* bubble) {
   if (bubbles_.insert(bubble).second) {
     bubble->AddObserver(this);
@@ -177,7 +201,7 @@
   }
 }
 
-void ImmersiveFullscreenController::BubbleManager::StopObserving(
+void ImmersiveFullscreenController::BubbleObserver::StopObserving(
     aura::Window* bubble) {
   if (bubbles_.erase(bubble)) {
     bubble->RemoveObserver(this);
@@ -185,7 +209,7 @@
   }
 }
 
-void ImmersiveFullscreenController::BubbleManager::UpdateRevealedLock() {
+void ImmersiveFullscreenController::BubbleObserver::UpdateRevealedLock() {
   bool has_visible_bubble = false;
   for (std::set<aura::Window*>::const_iterator it = bubbles_.begin();
        it != bubbles_.end(); ++it) {
@@ -216,18 +240,22 @@
     // visibility change.
     for (std::set<aura::Window*>::const_iterator it = bubbles_.begin();
          it != bubbles_.end(); ++it) {
-      AsBubbleDelegate(*it)->OnAnchorBoundsChanged();
+      views::BubbleDelegateView* bubble = AsBubbleDelegate(*it);
+      if (bubble)
+        bubble->OnAnchorBoundsChanged();
+      else
+        AsBubbleDialogDelegate(*it)->OnAnchorBoundsChanged();
     }
   }
 }
 
-void ImmersiveFullscreenController::BubbleManager::OnWindowVisibilityChanged(
+void ImmersiveFullscreenController::BubbleObserver::OnWindowVisibilityChanged(
     aura::Window*,
     bool visible) {
   UpdateRevealedLock();
 }
 
-void ImmersiveFullscreenController::BubbleManager::OnWindowDestroying(
+void ImmersiveFullscreenController::BubbleObserver::OnWindowDestroying(
     aura::Window* window) {
   StopObserving(window);
 }
@@ -489,21 +517,19 @@
 void ImmersiveFullscreenController::OnTransientChildAdded(
     aura::Window* window,
     aura::Window* transient) {
-  views::BubbleDelegateView* bubble_delegate = AsBubbleDelegate(transient);
-  if (bubble_delegate &&
-      bubble_delegate->GetAnchorView() &&
-      top_container_->Contains(bubble_delegate->GetAnchorView())) {
+  views::View* anchor = GetAnchorView(transient);
+  if (anchor && top_container_->Contains(anchor)) {
     // Observe the aura::Window because the BubbleDelegateView may not be
     // parented to the widget's root view yet so |bubble_delegate->GetWidget()|
     // may still return NULL.
-    bubble_manager_->StartObserving(transient);
+    bubble_observer_->StartObserving(transient);
   }
 }
 
 void ImmersiveFullscreenController::OnTransientChildRemoved(
     aura::Window* window,
     aura::Window* transient) {
-  bubble_manager_->StopObserving(transient);
+  bubble_observer_->StopObserving(transient);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -543,7 +569,7 @@
     ::wm::TransientWindowManager::Get(native_window_)->
         AddObserver(this);
 
-    RecreateBubbleManager();
+    RecreateBubbleObserver();
   } else {
     widget_->RemoveObserver(this);
     focus_manager->RemoveFocusChangeListener(this);
@@ -552,10 +578,10 @@
         RemoveObserver(this);
 
     // We have stopped observing whether transient children are added or removed
-    // to |native_window_|. The set of bubbles that BubbleManager is observing
-    // will become stale really quickly. Destroy BubbleManager and recreate it
+    // to |native_window_|. The set of bubbles that BubbleObserver is observing
+    // will become stale really quickly. Destroy BubbleObserver and recreate it
     // when we start observing |native_window_| again.
-    bubble_manager_.reset();
+    bubble_observer_.reset();
 
     animation_->Stop();
   }
@@ -705,10 +731,8 @@
   } else {
     aura::Window* active_window = aura::client::GetActivationClient(
         native_window_->GetRootWindow())->GetActiveWindow();
-    views::BubbleDelegateView* bubble_delegate =
-        AsBubbleDelegate(active_window);
-    if (bubble_delegate && bubble_delegate->anchor_widget()) {
-      // BubbleManager will already have locked the top-of-window views if the
+    if (GetAnchorView(active_window)) {
+      // BubbleObserver will already have locked the top-of-window views if the
       // bubble is anchored to a child of |top_container_|. Don't acquire
       // |focus_revealed_lock_| here for the sake of simplicity.
       // Note: Instead of checking for the existence of the |anchor_view|,
@@ -933,19 +957,15 @@
           location.x() < hit_bounds_in_screen.right());
 }
 
-void ImmersiveFullscreenController::RecreateBubbleManager() {
-  bubble_manager_.reset(new BubbleManager(this));
+void ImmersiveFullscreenController::RecreateBubbleObserver() {
+  bubble_observer_.reset(new BubbleObserver(this));
   const std::vector<aura::Window*> transient_children =
       ::wm::GetTransientChildren(native_window_);
   for (size_t i = 0; i < transient_children.size(); ++i) {
     aura::Window* transient_child = transient_children[i];
-    views::BubbleDelegateView* bubble_delegate =
-        AsBubbleDelegate(transient_child);
-    if (bubble_delegate &&
-        bubble_delegate->GetAnchorView() &&
-        top_container_->Contains(bubble_delegate->GetAnchorView())) {
-      bubble_manager_->StartObserving(transient_child);
-    }
+    views::View* anchor_view = GetAnchorView(transient_child);
+    if (anchor_view && top_container_->Contains(anchor_view))
+      bubble_observer_->StartObserving(transient_child);
   }
 }
 
diff --git a/ash/wm/immersive_fullscreen_controller.h b/ash/wm/immersive_fullscreen_controller.h
index 8b3f141..a9d7614 100644
--- a/ash/wm/immersive_fullscreen_controller.h
+++ b/ash/wm/immersive_fullscreen_controller.h
@@ -238,9 +238,9 @@
   // is a bezel sensor above the top container.
   bool ShouldHandleGestureEvent(const gfx::Point& location) const;
 
-  // Recreate |bubble_manager_| and start observing any bubbles anchored to a
+  // Recreate |bubble_observer_| and start observing any bubbles anchored to a
   // child of |top_container_|.
-  void RecreateBubbleManager();
+  void RecreateBubbleObserver();
 
   // Not owned.
   Delegate* delegate_;
@@ -288,8 +288,8 @@
   bool animations_disabled_for_test_;
 
   // Manages bubbles which are anchored to a child of |top_container_|.
-  class BubbleManager;
-  scoped_ptr<BubbleManager> bubble_manager_;
+  class BubbleObserver;
+  scoped_ptr<BubbleObserver> bubble_observer_;
 
   base::WeakPtrFactory<ImmersiveFullscreenController> weak_ptr_factory_;
 
diff --git a/base/android/java/src/org/chromium/base/PathUtils.java b/base/android/java/src/org/chromium/base/PathUtils.java
index 9d53a96..5479859 100644
--- a/base/android/java/src/org/chromium/base/PathUtils.java
+++ b/base/android/java/src/org/chromium/base/PathUtils.java
@@ -104,7 +104,6 @@
         paths[DATA_DIRECTORY] = sDataDirectoryAppContext.getDir(sDataDirectorySuffix,
                 Context.MODE_PRIVATE).getPath();
         paths[DATABASE_DIRECTORY] = sDataDirectoryAppContext.getDatabasePath("foo").getParent();
-        // TODO(wnwen): Find a way to avoid calling this function in renderer process.
         if (sDataDirectoryAppContext.getCacheDir() != null) {
             paths[CACHE_DIRECTORY] = sDataDirectoryAppContext.getCacheDir().getPath();
         }
diff --git a/base/android/java/src/org/chromium/base/library_loader/ModernLinker.java b/base/android/java/src/org/chromium/base/library_loader/ModernLinker.java
index bff22c8..7716a8d 100644
--- a/base/android/java/src/org/chromium/base/library_loader/ModernLinker.java
+++ b/base/android/java/src/org/chromium/base/library_loader/ModernLinker.java
@@ -62,9 +62,6 @@
     // The map of libraries that are currently loaded in this process.
     private HashMap<String, LibInfo> mLoadedLibraries = null;
 
-    // The directory used to hold shared RELRO data files. Set up by prepareLibraryLoad().
-    private String mDataDirectory = null;
-
     // Private singleton constructor, and singleton factory method.
     private ModernLinker() { }
     static Linker create() {
@@ -122,9 +119,6 @@
             // Create an empty loaded libraries map.
             mLoadedLibraries = new HashMap<String, LibInfo>();
 
-            // Retrieve the data directory from base.
-            mDataDirectory = PathUtils.getDataDirectory(null);
-
             // Start the current load address at the base load address.
             mCurrentLoadAddress = mBaseLoadAddress;
 
@@ -394,7 +388,7 @@
                 // We are in the browser, and with a current load address that indicates that
                 // there is enough address space for shared RELRO to operate. Create the
                 // shared RELRO, and store it in the map.
-                String relroPath = mDataDirectory + "/RELRO:" + libFilePath;
+                String relroPath = PathUtils.getDataDirectory(null) + "/RELRO:" + libFilePath;
                 if (nativeCreateSharedRelro(dlopenExtPath,
                                             mCurrentLoadAddress, relroPath, libInfo)) {
                     mSharedRelros.put(dlopenExtPath, libInfo);
diff --git a/base/android/scoped_java_ref.h b/base/android/scoped_java_ref.h
index 8dcf2bca..a1b4b13f 100644
--- a/base/android/scoped_java_ref.h
+++ b/base/android/scoped_java_ref.h
@@ -8,10 +8,11 @@
 #include <jni.h>
 #include <stddef.h>
 
+#include <type_traits>
+
 #include "base/base_export.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/template_util.h"
 
 namespace base {
 namespace android {
@@ -193,7 +194,7 @@
 
   template<typename U>
   void Reset(JNIEnv* env, U obj) {
-    static_assert(base::is_convertible<U, T>::value,
+    static_assert(std::is_convertible<U, T>::value,
                   "U must be convertible to T");
     env_ = this->SetNewLocalRef(env, obj);
   }
@@ -264,7 +265,7 @@
 
   template<typename U>
   void Reset(JNIEnv* env, U obj) {
-    static_assert(base::is_convertible<U, T>::value,
+    static_assert(std::is_convertible<U, T>::value,
                   "U must be convertible to T");
     this->SetNewGlobalRef(env, obj);
   }
diff --git a/base/bind_helpers.h b/base/bind_helpers.h
index a551465ce8..117fc68 100644
--- a/base/bind_helpers.h
+++ b/base/bind_helpers.h
@@ -150,7 +150,6 @@
 
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
-#include "base/template_util.h"
 #include "build/build_config.h"
 
 namespace base {
@@ -262,21 +261,21 @@
 // Helpers to assert that arguments of a recounted type are bound with a
 // scoped_refptr.
 template <bool IsClasstype, typename T>
-struct UnsafeBindtoRefCountedArgHelper : false_type {
+struct UnsafeBindtoRefCountedArgHelper : std::false_type {
 };
 
 template <typename T>
 struct UnsafeBindtoRefCountedArgHelper<true, T>
-    : integral_constant<bool, SupportsAddRefAndRelease<T>::value> {
+    : std::integral_constant<bool, SupportsAddRefAndRelease<T>::value> {
 };
 
 template <typename T>
-struct UnsafeBindtoRefCountedArg : false_type {
+struct UnsafeBindtoRefCountedArg : std::false_type {
 };
 
 template <typename T>
 struct UnsafeBindtoRefCountedArg<T*>
-    : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> {
+    : UnsafeBindtoRefCountedArgHelper<std::is_class<T>::value, T> {
 };
 
 template <typename T>
@@ -433,14 +432,14 @@
 // The first argument should be the type of the object that will be received by
 // the method.
 template <bool IsMethod, typename... Args>
-struct IsWeakMethod : public false_type {};
+struct IsWeakMethod : public std::false_type {};
 
 template <typename T, typename... Args>
-struct IsWeakMethod<true, WeakPtr<T>, Args...> : public true_type {};
+struct IsWeakMethod<true, WeakPtr<T>, Args...> : public std::true_type {};
 
 template <typename T, typename... Args>
 struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T>>, Args...>
-    : public true_type {};
+    : public std::true_type {};
 
 
 // Packs a list of types to hold them in a single type.
diff --git a/base/bind_internal.h b/base/bind_internal.h
index 38a5756..199467c 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -68,7 +68,7 @@
 // Implementation note: This non-specialized case handles zero-arity case only.
 // Non-zero-arity cases should be handled by the specialization below.
 template <typename List>
-struct HasNonConstReferenceItem : false_type {};
+struct HasNonConstReferenceItem : std::false_type {};
 
 // Implementation note: Select true_type if the first parameter is a non-const
 // reference.  Otherwise, skip the first parameter and check rest of parameters
@@ -76,7 +76,7 @@
 template <typename T, typename... Args>
 struct HasNonConstReferenceItem<TypeList<T, Args...>>
     : std::conditional<is_non_const_reference<T>::value,
-                       true_type,
+                       std::true_type,
                        HasNonConstReferenceItem<TypeList<Args...>>>::type {};
 
 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw
@@ -84,7 +84,7 @@
 // Implementation note: This non-specialized case handles zero-arity case only.
 // Non-zero-arity cases should be handled by the specialization below.
 template <typename... Args>
-struct HasRefCountedTypeAsRawPtr : false_type {};
+struct HasRefCountedTypeAsRawPtr : std::false_type {};
 
 // Implementation note: Select true_type if the first parameter is a raw pointer
 // to a RefCounted type. Otherwise, skip the first parameter and check rest of
@@ -92,7 +92,7 @@
 template <typename T, typename... Args>
 struct HasRefCountedTypeAsRawPtr<T, Args...>
     : std::conditional<NeedsScopedRefptrButGetsRawPtr<T>::value,
-                       true_type,
+                       std::true_type,
                        HasRefCountedTypeAsRawPtr<Args...>>::type {};
 
 // BindsArrayToFirstArg selects true_type when |is_method| is true and the first
@@ -101,11 +101,11 @@
 // zero-arity case only.  Other cases should be handled by the specialization
 // below.
 template <bool is_method, typename... Args>
-struct BindsArrayToFirstArg : false_type {};
+struct BindsArrayToFirstArg : std::false_type {};
 
 template <typename T, typename... Args>
 struct BindsArrayToFirstArg<true, T, Args...>
-    : is_array<typename std::remove_reference<T>::type> {};
+    : std::is_array<typename std::remove_reference<T>::type> {};
 
 // HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except
 // when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument.
@@ -170,7 +170,7 @@
   // MSVC 2013 doesn't support Type Alias of function types.
   // Revisit this after we update it to newer version.
   typedef R RunType(T*, Args...);
-  using IsMethod = true_type;
+  using IsMethod = std::true_type;
 
   explicit RunnableAdapter(R(T::*method)(Args...))
       : method_(method) {
@@ -190,7 +190,7 @@
 class RunnableAdapter<R(T::*)(Args...) const> {
  public:
   using RunType = R(const T*, Args...);
-  using IsMethod = true_type;
+  using IsMethod = std::true_type;
 
   explicit RunnableAdapter(R(T::*method)(Args...) const)
       : method_(method) {
@@ -322,7 +322,7 @@
   // WeakCalls are only supported for functions with a void return type.
   // Otherwise, the function result would be undefined if the the WeakPtr<>
   // is invalidated.
-  static_assert(is_void<ReturnType>::value,
+  static_assert(std::is_void<ReturnType>::value,
                 "weak_ptrs can only bind to methods without return values");
 };
 
diff --git a/base/callback.h b/base/callback.h
index 5f73b7f9..c04e90d 100644
--- a/base/callback.h
+++ b/base/callback.h
@@ -7,7 +7,6 @@
 
 #include "base/callback_forward.h"
 #include "base/callback_internal.h"
-#include "base/template_util.h"
 
 // NOTE: Header files that do not require the full definition of Callback or
 // Closure should #include "base/callback_forward.h" instead of this file.
diff --git a/base/callback_internal.h b/base/callback_internal.h
index 7319614..16705578 100644
--- a/base/callback_internal.h
+++ b/base/callback_internal.h
@@ -19,7 +19,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/template_util.h"
 
 namespace base {
 namespace internal {
@@ -127,7 +126,13 @@
 // confuses template deduction in VS2013 with certain types such as
 // std::unique_ptr.
 // TODO(dcheng): Revisit this when Windows switches to VS2015 by default.
+
 template <typename T> struct IsMoveOnlyType {
+  // Types YesType and NoType are guaranteed such that sizeof(YesType) <
+  // sizeof(NoType).
+  using YesType = char;
+  struct NoType { YesType dummy[2]; };
+
   template <typename U>
   static YesType Test(const typename U::MoveOnlyTypeForCPP03*);
 
@@ -135,7 +140,7 @@
   static NoType Test(...);
 
   static const bool value = sizeof((Test<T>(0))) == sizeof(YesType) &&
-                            !is_const<T>::value;
+                            !std::is_const<T>::value;
 };
 
 // Specialization of IsMoveOnlyType so that std::unique_ptr is still considered
diff --git a/base/memory/raw_scoped_refptr_mismatch_checker.h b/base/memory/raw_scoped_refptr_mismatch_checker.h
index 1e88b487..5dbc183 100644
--- a/base/memory/raw_scoped_refptr_mismatch_checker.h
+++ b/base/memory/raw_scoped_refptr_mismatch_checker.h
@@ -5,10 +5,10 @@
 #ifndef BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
 #define BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
 
+#include <tuple>
+#include <type_traits>
+
 #include "base/memory/ref_counted.h"
-#include "base/template_util.h"
-#include "base/tuple.h"
-#include "build/build_config.h"
 
 // It is dangerous to post a task with a T* argument where T is a subtype of
 // RefCounted(Base|ThreadSafeBase), since by the time the parameter is used, the
@@ -25,20 +25,14 @@
 
 template <typename T>
 struct NeedsScopedRefptrButGetsRawPtr {
-#if defined(OS_WIN)
-  enum {
-    value = base::false_type::value
-  };
-#else
   enum {
     // Human readable translation: you needed to be a scoped_refptr if you are a
     // raw pointer type and are convertible to a RefCounted(Base|ThreadSafeBase)
     // type.
-    value = (is_pointer<T>::value &&
-             (is_convertible<T, subtle::RefCountedBase*>::value ||
-              is_convertible<T, subtle::RefCountedThreadSafeBase*>::value))
+    value = (std::is_pointer<T>::value &&
+             (std::is_convertible<T, subtle::RefCountedBase*>::value ||
+              std::is_convertible<T, subtle::RefCountedThreadSafeBase*>::value))
   };
-#endif
 };
 
 template <typename Params>
diff --git a/base/memory/scoped_ptr.h b/base/memory/scoped_ptr.h
index 358e9f18..db0d04b 100644
--- a/base/memory/scoped_ptr.h
+++ b/base/memory/scoped_ptr.h
@@ -102,7 +102,6 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/move.h"
-#include "base/template_util.h"
 #include "build/build_config.h"
 
 namespace base {
@@ -179,8 +178,8 @@
 
 template <typename T> struct IsNotRefCounted {
   enum {
-    value = !base::is_convertible<T*, base::subtle::RefCountedBase*>::value &&
-        !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>::
+    value = !std::is_convertible<T*, base::subtle::RefCountedBase*>::value &&
+        !std::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>::
             value
   };
 };
diff --git a/base/memory/weak_ptr.h b/base/memory/weak_ptr.h
index 4e50c27..9ba5e25c 100644
--- a/base/memory/weak_ptr.h
+++ b/base/memory/weak_ptr.h
@@ -70,12 +70,13 @@
 #ifndef BASE_MEMORY_WEAK_PTR_H_
 #define BASE_MEMORY_WEAK_PTR_H_
 
+#include <type_traits>
+
 #include "base/base_export.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequence_checker.h"
-#include "base/template_util.h"
 
 namespace base {
 
@@ -160,8 +161,8 @@
   // function that makes calling this easier.
   template<typename Derived>
   static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) {
-    typedef
-        is_convertible<Derived, internal::SupportsWeakPtrBase&> convertible;
+    using convertible =
+        std::is_convertible<Derived*, internal::SupportsWeakPtrBase*>;
     static_assert(convertible::value,
                   "AsWeakPtr argument must inherit from SupportsWeakPtr");
     return AsWeakPtrImpl<Derived>(t, *t);
diff --git a/base/numerics/safe_numerics_unittest.cc b/base/numerics/safe_numerics_unittest.cc
index cb63ad0..861f515 100644
--- a/base/numerics/safe_numerics_unittest.cc
+++ b/base/numerics/safe_numerics_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/compiler_specific.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/numerics/safe_math.h"
-#include "base/template_util.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/base/template_util.h b/base/template_util.h
index d58807a..0c3cac2 100644
--- a/base/template_util.h
+++ b/base/template_util.h
@@ -5,117 +5,15 @@
 #ifndef BASE_TEMPLATE_UTIL_H_
 #define BASE_TEMPLATE_UTIL_H_
 
-#include <stddef.h>
+#include <type_traits>
 
 #include "build/build_config.h"
 
 namespace base {
 
-// template definitions from tr1
-
-template<class T, T v>
-struct integral_constant {
-  static const T value = v;
-  typedef T value_type;
-  typedef integral_constant<T, v> type;
-};
-
-template <class T, T v> const T integral_constant<T, v>::value;
-
-typedef integral_constant<bool, true> true_type;
-typedef integral_constant<bool, false> false_type;
-
-template <class T> struct is_pointer : false_type {};
-template <class T> struct is_pointer<T*> : true_type {};
-
-// Member function pointer detection. This is built-in to C++ 11's stdlib, and
-// we can remove this when we switch to it.
-template<typename T>
-struct is_member_function_pointer : false_type {};
-
-template <typename R, typename Z, typename... A>
-struct is_member_function_pointer<R(Z::*)(A...)> : true_type {};
-template <typename R, typename Z, typename... A>
-struct is_member_function_pointer<R(Z::*)(A...) const> : true_type {};
-
-
-template <class T, class U> struct is_same : public false_type {};
-template <class T> struct is_same<T,T> : true_type {};
-
-template<class> struct is_array : public false_type {};
-template<class T, size_t n> struct is_array<T[n]> : public true_type {};
-template<class T> struct is_array<T[]> : public true_type {};
-
-template <class T> struct is_non_const_reference : false_type {};
-template <class T> struct is_non_const_reference<T&> : true_type {};
-template <class T> struct is_non_const_reference<const T&> : false_type {};
-
-template <class T> struct is_const : false_type {};
-template <class T> struct is_const<const T> : true_type {};
-
-template <class T> struct is_void : false_type {};
-template <> struct is_void<void> : true_type {};
-
-namespace internal {
-
-// Types YesType and NoType are guaranteed such that sizeof(YesType) <
-// sizeof(NoType).
-typedef char YesType;
-
-struct NoType {
-  YesType dummy[2];
-};
-
-// This class is an implementation detail for is_convertible, and you
-// don't need to know how it works to use is_convertible. For those
-// who care: we declare two different functions, one whose argument is
-// of type To and one with a variadic argument list. We give them
-// return types of different size, so we can use sizeof to trick the
-// compiler into telling us which function it would have chosen if we
-// had called it with an argument of type From.  See Alexandrescu's
-// _Modern C++ Design_ for more details on this sort of trick.
-
-struct ConvertHelper {
-  template <typename To>
-  static YesType Test(To);
-
-  template <typename To>
-  static NoType Test(...);
-
-  template <typename From>
-  static From& Create();
-};
-
-// Used to determine if a type is a struct/union/class. Inspired by Boost's
-// is_class type_trait implementation.
-struct IsClassHelper {
-  template <typename C>
-  static YesType Test(void(C::*)(void));
-
-  template <typename C>
-  static NoType Test(...);
-};
-
-}  // namespace internal
-
-// Inherits from true_type if From is convertible to To, false_type otherwise.
-//
-// Note that if the type is convertible, this will be a true_type REGARDLESS
-// of whether or not the conversion would emit a warning.
-template <typename From, typename To>
-struct is_convertible
-    : integral_constant<bool,
-                        sizeof(internal::ConvertHelper::Test<To>(
-                                   internal::ConvertHelper::Create<From>())) ==
-                        sizeof(internal::YesType)> {
-};
-
-template <typename T>
-struct is_class
-    : integral_constant<bool,
-                        sizeof(internal::IsClassHelper::Test<T>(0)) ==
-                            sizeof(internal::YesType)> {
-};
+template <class T> struct is_non_const_reference : std::false_type {};
+template <class T> struct is_non_const_reference<T&> : std::true_type {};
+template <class T> struct is_non_const_reference<const T&> : std::false_type {};
 
 }  // namespace base
 
diff --git a/base/template_util_unittest.cc b/base/template_util_unittest.cc
index b960ab1c..25441cda 100644
--- a/base/template_util_unittest.cc
+++ b/base/template_util_unittest.cc
@@ -9,99 +9,11 @@
 namespace base {
 namespace {
 
-struct AStruct {};
-class AClass {};
-enum AnEnum {};
-
-class Parent {};
-class Child : public Parent {};
-
-// is_pointer<Type>
-static_assert(!is_pointer<int>::value, "IsPointer");
-static_assert(!is_pointer<int&>::value, "IsPointer");
-static_assert(is_pointer<int*>::value, "IsPointer");
-static_assert(is_pointer<const int*>::value, "IsPointer");
-
-// is_array<Type>
-static_assert(!is_array<int>::value, "IsArray");
-static_assert(!is_array<int*>::value, "IsArray");
-static_assert(!is_array<int (*)[3]>::value, "IsArray");
-static_assert(is_array<int[]>::value, "IsArray");
-static_assert(is_array<const int[]>::value, "IsArray");
-static_assert(is_array<int[3]>::value, "IsArray");
-
 // is_non_const_reference<Type>
 static_assert(!is_non_const_reference<int>::value, "IsNonConstReference");
 static_assert(!is_non_const_reference<const int&>::value,
               "IsNonConstReference");
 static_assert(is_non_const_reference<int&>::value, "IsNonConstReference");
 
-// is_convertible<From, To>
-
-// Extra parens needed to make preprocessor macro parsing happy. Otherwise,
-// it sees the equivalent of:
-//
-//     (is_convertible < Child), (Parent > ::value)
-//
-// Silly C++.
-static_assert((is_convertible<Child, Parent>::value), "IsConvertible");
-static_assert(!(is_convertible<Parent, Child>::value), "IsConvertible");
-static_assert(!(is_convertible<Parent, AStruct>::value), "IsConvertible");
-static_assert((is_convertible<int, double>::value), "IsConvertible");
-static_assert((is_convertible<int*, void*>::value), "IsConvertible");
-static_assert(!(is_convertible<void*, int*>::value), "IsConvertible");
-
-// Array types are an easy corner case.  Make sure to test that
-// it does indeed compile.
-static_assert(!(is_convertible<int[10], double>::value), "IsConvertible");
-static_assert(!(is_convertible<double, int[10]>::value), "IsConvertible");
-static_assert((is_convertible<int[10], int*>::value), "IsConvertible");
-
-// is_same<Type1, Type2>
-static_assert(!(is_same<Child, Parent>::value), "IsSame");
-static_assert(!(is_same<Parent, Child>::value), "IsSame");
-static_assert((is_same<Parent, Parent>::value), "IsSame");
-static_assert((is_same<int*, int*>::value), "IsSame");
-static_assert((is_same<int, int>::value), "IsSame");
-static_assert((is_same<void, void>::value), "IsSame");
-static_assert(!(is_same<int, double>::value), "IsSame");
-
-// is_class<Type>
-static_assert(is_class<AStruct>::value, "IsClass");
-static_assert(is_class<AClass>::value, "IsClass");
-static_assert(!is_class<AnEnum>::value, "IsClass");
-static_assert(!is_class<int>::value, "IsClass");
-static_assert(!is_class<char*>::value, "IsClass");
-static_assert(!is_class<int&>::value, "IsClass");
-static_assert(!is_class<char[3]>::value, "IsClass");
-
-static_assert(!is_member_function_pointer<int>::value,
-              "IsMemberFunctionPointer");
-static_assert(!is_member_function_pointer<int*>::value,
-              "IsMemberFunctionPointer");
-static_assert(!is_member_function_pointer<void*>::value,
-              "IsMemberFunctionPointer");
-static_assert(!is_member_function_pointer<AStruct>::value,
-              "IsMemberFunctionPointer");
-static_assert(!is_member_function_pointer<AStruct*>::value,
-              "IsMemberFunctionPointer");
-static_assert(!is_member_function_pointer<void (*)()>::value,
-              "IsMemberFunctionPointer");
-static_assert(!is_member_function_pointer<int (*)(int)>::value,
-              "IsMemberFunctionPointer");
-static_assert(!is_member_function_pointer<int (*)(int, int)>::value,
-              "IsMemberFunctionPointer");
-
-static_assert(is_member_function_pointer<void (AStruct::*)()>::value,
-              "IsMemberFunctionPointer");
-static_assert(is_member_function_pointer<void (AStruct::*)(int)>::value,
-              "IsMemberFunctionPointer");
-static_assert(is_member_function_pointer<int (AStruct::*)(int)>::value,
-              "IsMemberFunctionPointer");
-static_assert(is_member_function_pointer<int (AStruct::*)(int) const>::value,
-              "IsMemberFunctionPointer");
-static_assert(is_member_function_pointer<int (AStruct::*)(int, int)>::value,
-              "IsMemberFunctionPointer");
-
 }  // namespace
 }  // namespace base
diff --git a/blimp/client/feature/compositor/decoding_image_generator.cc b/blimp/client/feature/compositor/decoding_image_generator.cc
index b2239c53..692dd373 100644
--- a/blimp/client/feature/compositor/decoding_image_generator.cc
+++ b/blimp/client/feature/compositor/decoding_image_generator.cc
@@ -47,10 +47,13 @@
   return true;
 }
 
-bool DecodingImageGenerator::onGetYUV8Planes(SkISize sizes[3],
-                                             void* planes[3],
-                                             size_t rowBytes[3],
-                                             SkYUVColorSpace*) {
+bool DecodingImageGenerator::onQueryYUV8(SkYUVSizeInfo* sizeInfo,
+                                         SkYUVColorSpace* colorSpace) const {
+  return false;
+}
+
+bool DecodingImageGenerator::onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo,
+                                             void* planes[3]) {
   return false;
 }
 
diff --git a/blimp/client/feature/compositor/decoding_image_generator.h b/blimp/client/feature/compositor/decoding_image_generator.h
index 1062cb8..3a3d2de 100644
--- a/blimp/client/feature/compositor/decoding_image_generator.h
+++ b/blimp/client/feature/compositor/decoding_image_generator.h
@@ -30,10 +30,11 @@
                    SkPMColor table[],
                    int* tableCount) override;
 
-  bool onGetYUV8Planes(SkISize sizes[3],
-                       void* planes[3],
-                       size_t rowBytes[3],
-                       SkYUVColorSpace*) override;
+  bool onQueryYUV8(SkYUVSizeInfo* sizeInfo,
+                   SkYUVColorSpace* colorSpace) const override;
+
+  bool onGetYUV8Planes(const SkYUVSizeInfo&,
+                       void* planes[3]) override;
 
  private:
   SkBitmap decoded_bitmap_;
diff --git a/blimp/engine/session/blimp_engine_session.cc b/blimp/engine/session/blimp_engine_session.cc
index 5ba532c..9543a83d 100644
--- a/blimp/engine/session/blimp_engine_session.cc
+++ b/blimp/engine/session/blimp_engine_session.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "base/strings/utf_string_conversions.h"
+#include "base/thread_task_runner_handle.h"
 #include "blimp/common/create_blimp_message.h"
 #include "blimp/common/proto/tab_control.pb.h"
 #include "blimp/engine/app/blimp_engine_config.h"
@@ -72,14 +73,32 @@
   return net::IPAddress(0, 0, 0, 0);
 }
 
+// Proxies calls to TaskRunner::PostTask while stripping the return value,
+// which provides a suitable function prototype for binding a base::Closure.
+void PostTask(const scoped_refptr<base::TaskRunner>& task_runner,
+              const base::Closure& closure) {
+  task_runner->PostTask(FROM_HERE, closure);
+}
+
+// Returns a closure that quits the current (bind-time) MessageLoop.
+base::Closure QuitCurrentMessageLoopClosure() {
+  return base::Bind(&PostTask, base::ThreadTaskRunnerHandle::Get(),
+                    base::MessageLoop::QuitWhenIdleClosure());
+}
+
 }  // namespace
 
 // EngineNetworkComponents is created by the BlimpEngineSession on the UI
 // thread, and then used and destroyed on the IO thread.
-class EngineNetworkComponents {
+class EngineNetworkComponents : public ConnectionHandler,
+                                public ConnectionErrorObserver {
  public:
-  explicit EngineNetworkComponents(net::NetLog* net_log);
-  ~EngineNetworkComponents();
+  // |net_log|: The log to use for network-related events.
+  // |quit_closure|: A closure which will terminate the engine when
+  //                 invoked.
+  EngineNetworkComponents(net::NetLog* net_log,
+                          const base::Closure& quit_closure);
+  ~EngineNetworkComponents() override;
 
   // Sets up network components and starts listening for incoming connection.
   // This should be called after all features have been registered so that
@@ -89,7 +108,17 @@
   BrowserConnectionHandler* GetBrowserConnectionHandler();
 
  private:
+  // ConnectionHandler implementation.
+  void HandleConnection(scoped_ptr<BlimpConnection> connection) override;
+
+  // ConnectionErrorObserver implementation.
+  // Signals the engine session that an authenticated connection was
+  // terminated.
+  void OnConnectionError(int error) override;
+
   net::NetLog* net_log_;
+  base::Closure quit_closure_;
+
   scoped_ptr<BrowserConnectionHandler> connection_handler_;
   scoped_ptr<EngineAuthenticationHandler> authentication_handler_;
   scoped_ptr<EngineConnectionManager> connection_manager_;
@@ -97,8 +126,12 @@
   DISALLOW_COPY_AND_ASSIGN(EngineNetworkComponents);
 };
 
-EngineNetworkComponents::EngineNetworkComponents(net::NetLog* net_log)
-    : net_log_(net_log), connection_handler_(new BrowserConnectionHandler) {}
+EngineNetworkComponents::EngineNetworkComponents(
+    net::NetLog* net_log,
+    const base::Closure& quit_closure)
+    : net_log_(net_log),
+      quit_closure_(quit_closure),
+      connection_handler_(new BrowserConnectionHandler) {}
 
 EngineNetworkComponents::~EngineNetworkComponents() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@@ -108,11 +141,12 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   DCHECK(!connection_manager_);
 
-  // Creates and connects net components.
-  // A BlimpConnection flows from
-  // connection_manager_ --> authentication_handler_ --> connection_handler_
-  authentication_handler_ = make_scoped_ptr(
-      new EngineAuthenticationHandler(connection_handler_.get(), client_token));
+  // Plumb authenticated connections from the authentication handler
+  // to |this| (which will then pass it to |connection_handler_|.
+  authentication_handler_ =
+      make_scoped_ptr(new EngineAuthenticationHandler(this, client_token));
+
+  // Plumb unauthenticated connections to |authentication_handler_|.
   connection_manager_ = make_scoped_ptr(
       new EngineConnectionManager(authentication_handler_.get()));
 
@@ -122,6 +156,18 @@
       make_scoped_ptr(new TCPEngineTransport(address, net_log_)));
 }
 
+void EngineNetworkComponents::HandleConnection(
+    scoped_ptr<BlimpConnection> connection) {
+  // Observe |connection| for disconnection events.
+  connection->AddConnectionErrorObserver(this);
+  connection_handler_->HandleConnection(std::move(connection));
+}
+
+void EngineNetworkComponents::OnConnectionError(int error) {
+  DVLOG(1) << "EngineNetworkComponents::OnConnectionError(" << error << ")";
+  quit_closure_.Run();
+}
+
 BrowserConnectionHandler*
 EngineNetworkComponents::GetBrowserConnectionHandler() {
   return connection_handler_.get();
@@ -134,7 +180,9 @@
     : browser_context_(std::move(browser_context)),
       engine_config_(engine_config),
       screen_(new BlimpScreen),
-      net_components_(new EngineNetworkComponents(net_log)) {
+      net_components_(
+          new EngineNetworkComponents(net_log,
+                                      QuitCurrentMessageLoopClosure())) {
   DCHECK(engine_config_);
   screen_->UpdateDisplayScaleAndSize(kDefaultScaleFactor,
                                      gfx::Size(kDefaultDisplayWidth,
@@ -145,6 +193,10 @@
 BlimpEngineSession::~BlimpEngineSession() {
   render_widget_feature_.RemoveDelegate(kDummyTabId);
 
+  // Ensure that all WebContents are torn down first, since teardown will
+  // trigger RenderViewDeleted callbacks to their observers.
+  web_contents_.reset();
+
   // Safely delete network components on the IO thread.
   content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE,
                                      net_components_.release());
diff --git a/build/all.gyp b/build/all.gyp
index 68a52f4a..280dcdda 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -434,6 +434,7 @@
         ['chromeos==1', {
           'dependencies': [
             '../ui/chromeos/ui_chromeos.gyp:ui_chromeos_unittests',
+            '../ui/arc/arc.gyp:ui_arc_unittests',
           ],
         }],
         ['OS=="linux"', {
diff --git a/build/common.gypi b/build/common.gypi
index 32022960d..b1b14d1 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -2244,7 +2244,9 @@
         'use_allocator%': 'none',
         'use_sanitizer_options%': 1,
       }],
-
+      ['OS=="linux" and asan==0 and msan==0 and lsan==0 and tsan==0 and build_for_tool==""', {
+        'use_experimental_allocator_shim%': 1,
+      }],
       ['OS=="linux" and asan==0 and msan==0 and lsan==0 and tsan==0', {
         # PNaCl toolchain Non-SFI build only supports linux OS build.
         # Also, it does not support sanitizers.
diff --git a/build/config/allocator.gni b/build/config/allocator.gni
index 2c908fe..c79f930b 100644
--- a/build/config/allocator.gni
+++ b/build/config/allocator.gni
@@ -11,6 +11,12 @@
   _default_allocator = "tcmalloc"
 }
 
+if (is_linux && !is_asan && !is_lsan && !is_tsan && !is_msan) {
+  _default_use_experimental_allocator_shim = true
+} else {
+  _default_use_experimental_allocator_shim = false
+}
+
 declare_args() {
   # Memory allocator to use. Set to "none" to use default allocator.
   use_allocator = _default_allocator
@@ -18,7 +24,7 @@
   # TODO(primiano): this should just become the default without having a flag,
   # but we need to get there first. http://crbug.com/550886 .
   # Causes all the allocations to be routed via allocator_shim.cc.
-  use_experimental_allocator_shim = false
+  use_experimental_allocator_shim = _default_use_experimental_allocator_shim
 }
 
 assert(use_allocator == "none" || use_allocator == "tcmalloc")
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi
index 924e533..5d0f7db 100644
--- a/build/gn_migration.gypi
+++ b/build/gn_migration.gypi
@@ -389,6 +389,7 @@
           'dependencies': [
             '../chromeos/chromeos.gyp:chromeos_unittests',
             '../ui/chromeos/ui_chromeos.gyp:ui_chromeos_unittests',
+            '../ui/arc/arc.gyp:ui_arc_unittests',
           ]
         }],
         ['chromeos==1 or OS=="win" or OS=="mac"', {
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 68b4e069..011c1a57 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -885,7 +885,6 @@
     "trees/layer_tree_host_pixeltest_tiles.cc",
     "trees/layer_tree_host_unittest.cc",
     "trees/layer_tree_host_unittest_animation.cc",
-    "trees/layer_tree_host_unittest_animation_timelines.cc",
     "trees/layer_tree_host_unittest_context.cc",
     "trees/layer_tree_host_unittest_copyrequest.cc",
     "trees/layer_tree_host_unittest_damage.cc",
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index ba0279e..37a56cb7 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -135,7 +135,6 @@
       'trees/layer_tree_host_pixeltest_tiles.cc',
       'trees/layer_tree_host_unittest.cc',
       'trees/layer_tree_host_unittest_animation.cc',
-      'trees/layer_tree_host_unittest_animation_timelines.cc',
       'trees/layer_tree_host_unittest_context.cc',
       'trees/layer_tree_host_unittest_copyrequest.cc',
       'trees/layer_tree_host_unittest_damage.cc',
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index 0503aa3..cff38e5 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -7,6 +7,11 @@
 #include <stdint.h>
 
 #include "cc/animation/animation_curve.h"
+#include "cc/animation/animation_host.h"
+#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_player.h"
+#include "cc/animation/animation_timeline.h"
+#include "cc/animation/element_animations.h"
 #include "cc/animation/layer_animation_controller.h"
 #include "cc/animation/scroll_offset_animation_curve.h"
 #include "cc/animation/timing_function.h"
@@ -26,18 +31,39 @@
 
 class LayerTreeHostAnimationTest : public LayerTreeTest {
  public:
+  LayerTreeHostAnimationTest()
+      : timeline_id_(AnimationIdProvider::NextTimelineId()),
+        player_id_(AnimationIdProvider::NextPlayerId()),
+        player_child_id_(AnimationIdProvider::NextPlayerId()) {
+    timeline_ = AnimationTimeline::Create(timeline_id_);
+    player_ = AnimationPlayer::Create(player_id_);
+    player_child_ = AnimationPlayer::Create(player_child_id_);
+
+    player_->set_layer_animation_delegate(this);
+  }
+
   void InitializeSettings(LayerTreeSettings* settings) override {
-    settings->use_compositor_animation_timelines = false;
+    settings->use_compositor_animation_timelines = true;
   }
 
   void InitializeLayerSettings(LayerSettings* layer_settings) override {
-    layer_settings->use_compositor_animation_timelines = false;
+    layer_settings->use_compositor_animation_timelines = true;
   }
 
-  void SetupTree() override {
-    LayerTreeTest::SetupTree();
-    layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
+  void AttachPlayersToTimeline() {
+    layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get());
+    timeline_->AttachPlayer(player_.get());
+    timeline_->AttachPlayer(player_child_.get());
   }
+
+ protected:
+  scoped_refptr<AnimationTimeline> timeline_;
+  scoped_refptr<AnimationPlayer> player_;
+  scoped_refptr<AnimationPlayer> player_child_;
+
+  const int timeline_id_;
+  const int player_id_;
+  const int player_child_id_;
 };
 
 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
@@ -126,7 +152,9 @@
       : update_animation_state_was_called_(false) {}
 
   void BeginTest() override {
-    PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
+    AttachPlayersToTimeline();
+    player_->AttachLayer(layer_tree_host()->root_layer()->id());
+    PostAddInstantAnimationToMainThreadPlayer(player_.get());
   }
 
   void UpdateAnimationState(LayerTreeHostImpl* host_impl,
@@ -141,10 +169,10 @@
     EXPECT_LT(base::TimeTicks(), monotonic_time);
 
     LayerAnimationController* controller =
-        layer_tree_host()->root_layer()->layer_animation_controller();
+        player_->element_animations()->layer_animation_controller();
     Animation* animation = controller->GetAnimation(TargetProperty::OPACITY);
     if (animation)
-      controller->RemoveAnimation(animation->id());
+      player_->RemoveAnimation(animation->id());
 
     EndTest();
   }
@@ -166,7 +194,9 @@
       : started_animating_(false) {}
 
   void BeginTest() override {
-    PostAddAnimationToMainThread(layer_tree_host()->root_layer());
+    AttachPlayersToTimeline();
+    player_->AttachLayer(layer_tree_host()->root_layer()->id());
+    PostAddAnimationToMainThreadPlayer(player_.get());
   }
 
   void AnimateLayers(LayerTreeHostImpl* host_impl,
@@ -202,12 +232,15 @@
       : started_animating_(false) {}
 
   void BeginTest() override {
-    PostAddAnimationToMainThread(layer_tree_host()->root_layer());
+    AttachPlayersToTimeline();
+    player_->AttachLayer(layer_tree_host()->root_layer()->id());
+    PostAddAnimationToMainThreadPlayer(player_.get());
   }
 
   void AnimateLayers(LayerTreeHostImpl* host_impl,
                      base::TimeTicks monotonic_time) override {
-    bool have_animations = !host_impl->animation_registrar()
+    bool have_animations = !host_impl->animation_host()
+                                ->animation_registrar()
                                 ->active_animation_controllers_for_testing()
                                 .empty();
     if (!started_animating_ && have_animations) {
@@ -245,9 +278,14 @@
     picture_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(picture_->bounds());
     layer_tree_host()->root_layer()->AddChild(picture_);
+
+    AttachPlayersToTimeline();
+    player_child_->AttachLayer(picture_->id());
   }
 
-  void BeginTest() override { PostAddAnimationToMainThread(picture_.get()); }
+  void BeginTest() override {
+    PostAddAnimationToMainThreadPlayer(player_child_.get());
+  }
 
   void AnimateLayers(LayerTreeHostImpl* host_impl,
                      base::TimeTicks monotonic_time) override {
@@ -255,13 +293,20 @@
     // pending tree too.
     if (!host_impl->active_tree()->root_layer())
       return;
+
+    // Wait for the commit with the animation to happen.
+    if (host_impl->sync_tree()->source_frame_number() != 0)
+      return;
+
+    scoped_refptr<AnimationTimeline> timeline_impl =
+        host_impl->animation_host()->GetTimelineById(timeline_id_);
+    scoped_refptr<AnimationPlayer> player_child_impl =
+        timeline_impl->GetPlayerById(player_child_id_);
+
     LayerAnimationController* controller_impl =
-        host_impl->active_tree()->root_layer()->children()[0]->
-        layer_animation_controller();
+        player_child_impl->element_animations()->layer_animation_controller();
     Animation* animation =
         controller_impl->GetAnimation(TargetProperty::OPACITY);
-    if (!animation)
-      return;
 
     const FloatAnimationCurve* curve =
         animation->curve()->ToFloatAnimationCurve();
@@ -297,18 +342,23 @@
     picture_ = FakePictureLayer::Create(layer_settings(), &client_);
     picture_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(picture_->bounds());
-    picture_->set_layer_animation_delegate(this);
+
     layer_tree_host()->root_layer()->AddChild(picture_);
+
+    AttachPlayersToTimeline();
+    player_child_->set_layer_animation_delegate(this);
+    player_child_->AttachLayer(picture_->id());
   }
 
-  void BeginTest() override { PostAddAnimationToMainThread(picture_.get()); }
+  void BeginTest() override {
+    PostAddAnimationToMainThreadPlayer(player_child_.get());
+  }
 
   void NotifyAnimationStarted(base::TimeTicks monotonic_time,
                               TargetProperty::Type target_property,
                               int group) override {
     LayerAnimationController* controller =
-        layer_tree_host()->root_layer()->children()[0]->
-        layer_animation_controller();
+        player_child_->element_animations()->layer_animation_controller();
     Animation* animation = controller->GetAnimation(TargetProperty::OPACITY);
     main_start_time_ = animation->start_time();
     controller->RemoveAnimation(animation->id());
@@ -317,9 +367,13 @@
 
   void UpdateAnimationState(LayerTreeHostImpl* impl_host,
                             bool has_unfinished_animation) override {
+    scoped_refptr<AnimationTimeline> timeline_impl =
+        impl_host->animation_host()->GetTimelineById(timeline_id_);
+    scoped_refptr<AnimationPlayer> player_child_impl =
+        timeline_impl->GetPlayerById(player_child_id_);
+
     LayerAnimationController* controller =
-        impl_host->active_tree()->root_layer()->children()[0]->
-        layer_animation_controller();
+        player_child_impl->element_animations()->layer_animation_controller();
     Animation* animation = controller->GetAnimation(TargetProperty::OPACITY);
     if (!animation)
       return;
@@ -347,14 +401,16 @@
     : public LayerTreeHostAnimationTest {
  public:
   void BeginTest() override {
-    PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
+    AttachPlayersToTimeline();
+    player_->AttachLayer(layer_tree_host()->root_layer()->id());
+    PostAddInstantAnimationToMainThreadPlayer(player_.get());
   }
 
   void NotifyAnimationFinished(base::TimeTicks monotonic_time,
                                TargetProperty::Type target_property,
                                int group) override {
     LayerAnimationController* controller =
-        layer_tree_host()->root_layer()->layer_animation_controller();
+        player_->element_animations()->layer_animation_controller();
     Animation* animation = controller->GetAnimation(TargetProperty::OPACITY);
     if (animation)
       controller->RemoveAnimation(animation->id());
@@ -381,15 +437,23 @@
     layer_tree_host()->SetRootLayer(update_check_layer_);
     client_.set_bounds(update_check_layer_->bounds());
     LayerTreeHostAnimationTest::SetupTree();
+
+    AttachPlayersToTimeline();
+    player_->AttachLayer(update_check_layer_->id());
   }
 
   void BeginTest() override {
-    PostAddAnimationToMainThread(update_check_layer_.get());
+    PostAddAnimationToMainThreadPlayer(player_.get());
   }
 
   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+    scoped_refptr<AnimationTimeline> timeline_impl =
+        host_impl->animation_host()->GetTimelineById(timeline_id_);
+    scoped_refptr<AnimationPlayer> player_impl =
+        timeline_impl->GetPlayerById(player_id_);
+
     LayerAnimationController* controller_impl =
-        host_impl->active_tree()->root_layer()->layer_animation_controller();
+        player_impl->element_animations()->layer_animation_controller();
     Animation* animation_impl =
         controller_impl->GetAnimation(TargetProperty::OPACITY);
     controller_impl->RemoveAnimation(animation_impl->id());
@@ -422,14 +486,17 @@
 
   void DidCommit() override {
     if (layer_tree_host()->source_frame_number() == 1) {
+      AttachPlayersToTimeline();
+
       scoped_refptr<Layer> layer = Layer::Create(layer_settings());
-      layer->set_layer_animation_delegate(this);
+      player_->AttachLayer(layer->id());
+      player_->set_layer_animation_delegate(this);
 
       // Any valid AnimationCurve will do here.
       scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
       scoped_ptr<Animation> animation(
           Animation::Create(std::move(curve), 1, 1, TargetProperty::OPACITY));
-      layer->layer_animation_controller()->AddAnimation(std::move(animation));
+      player_->AddAnimation(std::move(animation));
 
       // We add the animation *before* attaching the layer to the tree.
       layer_tree_host()->root_layer()->AddChild(layer);
@@ -570,15 +637,18 @@
     picture_ = FakePictureLayer::Create(layer_settings(), &client_);
     picture_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(picture_->bounds());
-    picture_->set_layer_animation_delegate(this);
     layer_tree_host()->root_layer()->AddChild(picture_);
+
+    AttachPlayersToTimeline();
+    player_child_->AttachLayer(picture_->id());
+    player_child_->set_layer_animation_delegate(this);
   }
 
   void InitializeSettings(LayerTreeSettings* settings) override {
-    LayerTreeHostAnimationTest::InitializeSettings(settings);
     // Make sure that drawing many times doesn't cause a checkerboarded
     // animation to start so we avoid flake in this test.
     settings->timeout_and_draw_when_animation_checkerboards = false;
+    LayerTreeHostAnimationTest::InitializeSettings(settings);
   }
 
   void BeginTest() override {
@@ -607,11 +677,12 @@
     switch (layer_tree_host()->source_frame_number()) {
       case 1:
         // The animation is longer than 1 BeginFrame interval.
-        AddOpacityTransitionToLayer(picture_.get(), 0.1, 0.2f, 0.8f, false);
+        AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 0.2f, 0.8f,
+                                     false);
         break;
       case 2:
         // This second animation will not be drawn so it should not start.
-        AddAnimatedTransformToLayer(picture_.get(), 0.1, 5, 5);
+        AddAnimatedTransformToPlayer(player_child_.get(), 0.1, 5, 5);
         break;
     }
   }
@@ -656,6 +727,9 @@
     client_.set_bounds(scroll_layer_->bounds());
     scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
     layer_tree_host()->root_layer()->AddChild(scroll_layer_);
+
+    AttachPlayersToTimeline();
+    player_child_->AttachLayer(scroll_layer_->id());
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -670,12 +744,11 @@
         scoped_ptr<Animation> animation(Animation::Create(
             std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
         animation->set_needs_synchronized_start_time(true);
-        bool animation_added =
-            scroll_layer_->AddAnimation(std::move(animation));
         bool impl_scrolling_supported =
             layer_tree_host()->proxy()->SupportsImplScrolling();
-        EXPECT_EQ(impl_scrolling_supported, animation_added);
-        if (!impl_scrolling_supported)
+        if (impl_scrolling_supported)
+          player_child_->AddAnimation(std::move(animation));
+        else
           EndTest();
         break;
       }
@@ -722,7 +795,10 @@
     scoped_ptr<Animation> animation(Animation::Create(
         std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
     animation->set_needs_synchronized_start_time(true);
-    scroll_layer_->AddAnimation(std::move(animation));
+
+    AttachPlayersToTimeline();
+    player_child_->AttachLayer(scroll_layer_->id());
+    player_child_->AddAnimation(std::move(animation));
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -733,10 +809,10 @@
         break;
       case 1: {
         Animation* animation =
-            scroll_layer_->layer_animation_controller()->GetAnimation(
-                TargetProperty::SCROLL_OFFSET);
-        scroll_layer_->layer_animation_controller()->RemoveAnimation(
-            animation->id());
+            player_child_->element_animations()
+                ->layer_animation_controller()
+                ->GetAnimation(TargetProperty::SCROLL_OFFSET);
+        player_child_->RemoveAnimation(animation->id());
         scroll_layer_->SetScrollOffset(final_postion_);
         break;
       }
@@ -759,11 +835,16 @@
       return;
     }
 
+    scoped_refptr<AnimationTimeline> timeline_impl =
+        host_impl->animation_host()->GetTimelineById(timeline_id_);
+    scoped_refptr<AnimationPlayer> player_impl =
+        timeline_impl->GetPlayerById(player_child_id_);
+
     LayerImpl* scroll_layer_impl =
         host_impl->active_tree()->root_layer()->children()[0].get();
-    Animation* animation =
-        scroll_layer_impl->layer_animation_controller()->GetAnimation(
-            TargetProperty::SCROLL_OFFSET);
+    Animation* animation = player_impl->element_animations()
+                               ->layer_animation_controller()
+                               ->GetAnimation(TargetProperty::SCROLL_OFFSET);
 
     if (!animation || animation->run_state() != Animation::RUNNING) {
       host_impl->BlockNotifyReadyToActivateForTesting(false);
@@ -817,20 +898,25 @@
   LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
       : frame_count_with_pending_tree_(0) {}
 
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+  void BeginTest() override {
+    AttachPlayersToTimeline();
+    PostSetNeedsCommitToMainThread();
+  }
 
   void DidCommit() override {
     if (layer_tree_host()->source_frame_number() == 1) {
-      AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
+      player_->AttachLayer(layer_tree_host()->root_layer()->id());
+      AddAnimatedTransformToPlayer(player_.get(), 4, 1, 1);
     } else if (layer_tree_host()->source_frame_number() == 2) {
-      AddOpacityTransitionToLayer(
-          layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
+      AddOpacityTransitionToPlayer(player_.get(), 1, 0.f, 0.5f, true);
 
       scoped_refptr<Layer> layer = Layer::Create(layer_settings());
       layer_tree_host()->root_layer()->AddChild(layer);
-      layer->set_layer_animation_delegate(this);
       layer->SetBounds(gfx::Size(4, 4));
-      AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true);
+
+      player_child_->AttachLayer(layer->id());
+      player_child_->set_layer_animation_delegate(this);
+      AddOpacityTransitionToPlayer(player_child_.get(), 1, 0.f, 0.5f, true);
     }
   }
 
@@ -862,16 +948,26 @@
 
   void UpdateAnimationState(LayerTreeHostImpl* host_impl,
                             bool has_unfinished_animation) override {
+    scoped_refptr<AnimationTimeline> timeline_impl =
+        host_impl->animation_host()->GetTimelineById(timeline_id_);
+    scoped_refptr<AnimationPlayer> player_impl =
+        timeline_impl->GetPlayerById(player_id_);
+    scoped_refptr<AnimationPlayer> player_child_impl =
+        timeline_impl->GetPlayerById(player_child_id_);
+
+    // wait for tree activation.
+    if (!player_impl->element_animations())
+      return;
+
     LayerAnimationController* root_controller_impl =
-        host_impl->active_tree()->root_layer()->layer_animation_controller();
+        player_impl->element_animations()->layer_animation_controller();
     Animation* root_animation =
         root_controller_impl->GetAnimation(TargetProperty::OPACITY);
     if (!root_animation || root_animation->run_state() != Animation::RUNNING)
       return;
 
     LayerAnimationController* child_controller_impl =
-        host_impl->active_tree()->root_layer()->children()
-            [0]->layer_animation_controller();
+        player_child_impl->element_animations()->layer_animation_controller();
     Animation* child_animation =
         child_controller_impl->GetAnimation(TargetProperty::OPACITY);
     EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
@@ -907,6 +1003,9 @@
     layer_->SetTransform(start_transform);
 
     layer_tree_host()->root_layer()->AddChild(layer_);
+    player_->AttachLayer(layer_->id());
+
+    AttachPlayersToTimeline();
   }
 
   void BeginTest() override {
@@ -915,7 +1014,7 @@
     start.AppendTranslate(6.f, 7.f, 0.f);
     TransformOperations end;
     end.AppendTranslate(8.f, 9.f, 0.f);
-    AddAnimatedTransformToLayer(layer_.get(), 4.0, start, end);
+    AddAnimatedTransformToPlayer(player_.get(), 4.0, start, end);
 
     PostSetNeedsCommitToMainThread();
   }
@@ -929,10 +1028,16 @@
     if (TestEnded())
       return;
 
+    scoped_refptr<AnimationTimeline> timeline_impl =
+        host_impl->animation_host()->GetTimelineById(timeline_id_);
+    scoped_refptr<AnimationPlayer> player_impl =
+        timeline_impl->GetPlayerById(player_id_);
+
+    LayerAnimationController* controller_impl =
+        player_impl->element_animations()->layer_animation_controller();
+
     LayerImpl* root = host_impl->sync_tree()->root_layer();
     LayerImpl* child = root->children()[0].get();
-    LayerAnimationController* controller_impl =
-        child->layer_animation_controller();
     Animation* animation =
         controller_impl->GetAnimation(TargetProperty::TRANSFORM);
 
@@ -970,7 +1075,13 @@
     layer_ = Layer::Create(layer_settings());
     layer_->SetBounds(gfx::Size(4, 4));
     layer_tree_host()->root_layer()->AddChild(layer_);
-    AddOpacityTransitionToLayer(layer_.get(), 10000.0, 0.1f, 0.9f, true);
+
+    layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get());
+    timeline_->AttachPlayer(player_.get());
+    player_->AttachLayer(layer_->id());
+    DCHECK(player_->element_animations());
+
+    AddOpacityTransitionToPlayer(player_.get(), 10000.0, 0.1f, 0.9f, true);
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -978,32 +1089,67 @@
   void DidCommit() override {
     switch (layer_tree_host()->source_frame_number()) {
       case 0:
-        EXPECT_TRUE(
-            layer_tree_host()->animation_registrar()->needs_animate_layers());
+        EXPECT_TRUE(player_->element_animations()
+                        ->has_active_value_observer_for_testing());
+        EXPECT_FALSE(player_->element_animations()
+                         ->has_pending_value_observer_for_testing());
+        EXPECT_TRUE(layer_tree_host()
+                        ->animation_host()
+                        ->animation_registrar()
+                        ->needs_animate_layers());
         break;
       case 1:
         layer_->RemoveFromParent();
-        EXPECT_TRUE(
-            layer_tree_host()->animation_registrar()->needs_animate_layers());
+        EXPECT_FALSE(player_->element_animations()
+                         ->has_active_value_observer_for_testing());
+        EXPECT_FALSE(player_->element_animations()
+                         ->has_pending_value_observer_for_testing());
+        EXPECT_TRUE(layer_tree_host()
+                        ->animation_host()
+                        ->animation_registrar()
+                        ->needs_animate_layers());
         break;
       case 2:
         layer_tree_host()->root_layer()->AddChild(layer_);
-        EXPECT_TRUE(
-            layer_tree_host()->animation_registrar()->needs_animate_layers());
+        EXPECT_TRUE(player_->element_animations()
+                        ->has_active_value_observer_for_testing());
+        EXPECT_FALSE(player_->element_animations()
+                         ->has_pending_value_observer_for_testing());
+        EXPECT_TRUE(layer_tree_host()
+                        ->animation_host()
+                        ->animation_registrar()
+                        ->needs_animate_layers());
         break;
     }
   }
 
   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+    scoped_refptr<AnimationTimeline> timeline_impl =
+        host_impl->animation_host()->GetTimelineById(timeline_id_);
+    scoped_refptr<AnimationPlayer> player_impl =
+        timeline_impl->GetPlayerById(player_id_);
+
     switch (host_impl->active_tree()->source_frame_number()) {
       case 0:
-        EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
+        EXPECT_TRUE(player_impl->element_animations()
+                        ->has_active_value_observer_for_testing());
+        EXPECT_TRUE(host_impl->animation_host()
+                        ->animation_registrar()
+                        ->needs_animate_layers());
         break;
       case 1:
-        EXPECT_FALSE(host_impl->animation_registrar()->needs_animate_layers());
+        EXPECT_FALSE(player_impl->element_animations()
+                         ->has_active_value_observer_for_testing());
+        EXPECT_TRUE(host_impl->animation_host()
+                        ->animation_registrar()
+                        ->needs_animate_layers());
         break;
       case 2:
-        EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
+        EXPECT_TRUE(player_impl->element_animations()
+                        ->has_active_value_observer_for_testing());
+        EXPECT_TRUE(host_impl->animation_host()
+                        ->animation_registrar()
+                        ->needs_animate_layers());
         EndTest();
         break;
     }
@@ -1026,6 +1172,11 @@
     layer_ = Layer::Create(layer_settings());
     layer_->SetBounds(gfx::Size(4, 4));
     layer_tree_host()->root_layer()->AddChild(layer_);
+
+    AttachPlayersToTimeline();
+
+    player_->AttachLayer(layer_tree_host()->root_layer()->id());
+    player_child_->AttachLayer(layer_->id());
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -1034,12 +1185,12 @@
     switch (layer_tree_host()->source_frame_number()) {
       case 1:
         // First frame: add an animation to the root layer.
-        AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
+        AddAnimatedTransformToPlayer(player_.get(), 0.1, 5, 5);
         break;
       case 2:
         // Second frame: add an animation to the content layer. The root layer
         // animation has caused us to animate already during this frame.
-        AddOpacityTransitionToLayer(layer_.get(), 0.1, 5, 5, false);
+        AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 5, 5, false);
         break;
     }
   }
@@ -1050,7 +1201,8 @@
     if (host_impl->active_tree()->source_frame_number() < 2)
       return;
     AnimationRegistrar::AnimationControllerMap controllers_copy =
-        host_impl->animation_registrar()
+        host_impl->animation_host()
+            ->animation_registrar()
             ->active_animation_controllers_for_testing();
     EXPECT_EQ(2u, controllers_copy.size());
     for (auto& it : controllers_copy) {
@@ -1084,6 +1236,11 @@
     layer_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(layer_->bounds());
     layer_tree_host()->root_layer()->AddChild(layer_);
+
+    AttachPlayersToTimeline();
+
+    player_->AttachLayer(layer_tree_host()->root_layer()->id());
+    player_child_->AttachLayer(layer_->id());
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -1091,14 +1248,14 @@
   void DidCommit() override {
     switch (layer_tree_host()->source_frame_number()) {
       case 1:
-        AddAnimatedTransformToLayer(layer_.get(), 1.0, 5, 5);
+        AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5);
         break;
       case 2:
         LayerAnimationController* controller =
-            layer_->layer_animation_controller();
+            player_child_->element_animations()->layer_animation_controller();
         Animation* animation =
             controller->GetAnimation(TargetProperty::TRANSFORM);
-        layer_->RemoveAnimation(animation->id());
+        player_child_->RemoveAnimation(animation->id());
         gfx::Transform transform;
         transform.Translate(10.f, 10.f);
         layer_->SetTransform(transform);
@@ -1161,6 +1318,9 @@
     layer_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(layer_->bounds());
     layer_tree_host()->root_layer()->AddChild(layer_);
+
+    AttachPlayersToTimeline();
+    player_->AttachLayer(layer_->id());
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -1168,14 +1328,14 @@
   void DidCommit() override {
     switch (layer_tree_host()->source_frame_number()) {
       case 1:
-        AddAnimatedTransformToLayer(layer_.get(), 1.0, 5, 5);
+        AddAnimatedTransformToPlayer(player_.get(), 1.0, 5, 5);
         break;
       case 2:
         LayerAnimationController* controller =
-            layer_->layer_animation_controller();
+            player_->element_animations()->layer_animation_controller();
         Animation* animation =
             controller->GetAnimation(TargetProperty::TRANSFORM);
-        layer_->RemoveAnimation(animation->id());
+        player_->RemoveAnimation(animation->id());
         break;
     }
   }
@@ -1243,13 +1403,18 @@
     layer_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(layer_->bounds());
     layer_tree_host()->root_layer()->AddChild(layer_);
+
+    AttachPlayersToTimeline();
+
+    player_->AttachLayer(layer_tree_host()->root_layer()->id());
+    player_child_->AttachLayer(layer_->id());
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
 
   void DidCommit() override {
     if (layer_tree_host()->source_frame_number() == 1)
-      AddAnimatedTransformToLayer(layer_.get(), 0.04, 5, 5);
+      AddAnimatedTransformToPlayer(player_child_.get(), 0.04, 5, 5);
   }
 
   void WillCommit() override {
@@ -1313,12 +1478,15 @@
     picture_ = FakePictureLayer::Create(layer_settings(), &client_);
     picture_->SetBounds(gfx::Size(4, 4));
     client_.set_bounds(picture_->bounds());
-    picture_->set_layer_animation_delegate(this);
     layer_tree_host()->root_layer()->AddChild(picture_);
+
+    AttachPlayersToTimeline();
+    player_->AttachLayer(picture_->id());
+    player_->set_layer_animation_delegate(this);
   }
 
   void BeginTest() override {
-    PostAddLongAnimationToMainThread(picture_.get());
+    PostAddLongAnimationToMainThreadPlayer(player_.get());
   }
 
   void NotifyAnimationStarted(base::TimeTicks monotonic_time,
@@ -1352,5 +1520,136 @@
 SINGLE_AND_MULTI_THREAD_TEST_F(
     LayerTreeHostAnimationTestNotifyAnimationFinished);
 
+// Check that SetTransformIsPotentiallyAnimatingChanged is called
+// if we destroy LayerAnimationController and ElementAnimations.
+class LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction
+    : public LayerTreeHostAnimationTest {
+ public:
+  void SetupTree() override {
+    prev_screen_space_transform_is_animating_ = true;
+    screen_space_transform_animation_stopped_ = false;
+
+    LayerTreeHostAnimationTest::SetupTree();
+    AttachPlayersToTimeline();
+    player_->AttachLayer(layer_tree_host()->root_layer()->id());
+    AddAnimatedTransformToPlayer(player_.get(), 1.0, 5, 5);
+  }
+
+  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+  void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
+    if (host_impl->pending_tree()->source_frame_number() <= 1) {
+      EXPECT_TRUE(host_impl->pending_tree()
+                      ->root_layer()
+                      ->screen_space_transform_is_animating());
+    } else {
+      EXPECT_FALSE(host_impl->pending_tree()
+                       ->root_layer()
+                       ->screen_space_transform_is_animating());
+    }
+  }
+
+  void DidCommit() override { PostSetNeedsCommitToMainThread(); }
+
+  void UpdateLayerTreeHost() override {
+    if (layer_tree_host()->source_frame_number() == 2) {
+      // Destroy player.
+      timeline_->DetachPlayer(player_.get());
+      player_ = nullptr;
+    }
+  }
+
+  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+                                   LayerTreeHostImpl::FrameData* frame_data,
+                                   DrawResult draw_result) override {
+    const bool screen_space_transform_is_animating =
+        host_impl->active_tree()
+            ->root_layer()
+            ->screen_space_transform_is_animating();
+
+    // Check that screen_space_transform_is_animating changes only once.
+    if (screen_space_transform_is_animating &&
+        prev_screen_space_transform_is_animating_)
+      EXPECT_FALSE(screen_space_transform_animation_stopped_);
+    if (!screen_space_transform_is_animating &&
+        prev_screen_space_transform_is_animating_) {
+      EXPECT_FALSE(screen_space_transform_animation_stopped_);
+      screen_space_transform_animation_stopped_ = true;
+    }
+    if (!screen_space_transform_is_animating &&
+        !prev_screen_space_transform_is_animating_)
+      EXPECT_TRUE(screen_space_transform_animation_stopped_);
+
+    prev_screen_space_transform_is_animating_ =
+        screen_space_transform_is_animating;
+
+    return draw_result;
+  }
+
+  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
+    if (host_impl->active_tree()->source_frame_number() >= 2)
+      EndTest();
+  }
+
+  void AfterTest() override {
+    EXPECT_TRUE(screen_space_transform_animation_stopped_);
+  }
+
+  bool prev_screen_space_transform_is_animating_;
+  bool screen_space_transform_animation_stopped_;
+};
+
+MULTI_THREAD_TEST_F(
+    LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction);
+
+// Check that we invalidate property trees on AnimationPlayer::SetNeedsCommit.
+class LayerTreeHostAnimationTestRebuildPropertyTreesOnAnimationSetNeedsCommit
+    : public LayerTreeHostAnimationTest {
+ public:
+  void SetupTree() override {
+    LayerTreeHostAnimationTest::SetupTree();
+    layer_ = FakePictureLayer::Create(layer_settings(), &client_);
+    layer_->SetBounds(gfx::Size(4, 4));
+    client_.set_bounds(layer_->bounds());
+    layer_tree_host()->root_layer()->AddChild(layer_);
+
+    AttachPlayersToTimeline();
+
+    player_->AttachLayer(layer_tree_host()->root_layer()->id());
+    player_child_->AttachLayer(layer_->id());
+  }
+
+  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+  void DidCommit() override {
+    if (layer_tree_host()->source_frame_number() == 1 ||
+        layer_tree_host()->source_frame_number() == 2)
+      PostSetNeedsCommitToMainThread();
+  }
+
+  void UpdateLayerTreeHost() override {
+    if (layer_tree_host()->source_frame_number() == 1) {
+      EXPECT_FALSE(layer_tree_host()->property_trees()->needs_rebuild);
+      AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5);
+    }
+
+    EXPECT_TRUE(layer_tree_host()->property_trees()->needs_rebuild);
+  }
+
+  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
+    if (host_impl->active_tree()->source_frame_number() >= 2)
+      EndTest();
+  }
+
+  void AfterTest() override {}
+
+ private:
+  scoped_refptr<Layer> layer_;
+  FakeContentLayerClient client_;
+};
+
+MULTI_THREAD_TEST_F(
+    LayerTreeHostAnimationTestRebuildPropertyTreesOnAnimationSetNeedsCommit);
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/trees/layer_tree_host_unittest_animation_timelines.cc b/cc/trees/layer_tree_host_unittest_animation_timelines.cc
deleted file mode 100644
index 1bd2696..0000000
--- a/cc/trees/layer_tree_host_unittest_animation_timelines.cc
+++ /dev/null
@@ -1,1453 +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 "cc/trees/layer_tree_host.h"
-
-#include "cc/animation/animation_curve.h"
-#include "cc/animation/animation_host.h"
-#include "cc/animation/animation_id_provider.h"
-#include "cc/animation/animation_player.h"
-#include "cc/animation/animation_timeline.h"
-#include "cc/animation/element_animations.h"
-#include "cc/animation/layer_animation_controller.h"
-#include "cc/animation/scroll_offset_animation_curve.h"
-#include "cc/animation/timing_function.h"
-#include "cc/base/completion_event.h"
-#include "cc/base/time_util.h"
-#include "cc/layers/layer.h"
-#include "cc/layers/layer_impl.h"
-#include "cc/test/animation_test_common.h"
-#include "cc/test/fake_content_layer_client.h"
-#include "cc/test/fake_picture_layer.h"
-#include "cc/test/layer_tree_test.h"
-#include "cc/trees/layer_tree_impl.h"
-
-namespace cc {
-namespace {
-
-class LayerTreeHostTimelinesTest : public LayerTreeTest {
- public:
-  LayerTreeHostTimelinesTest()
-      : timeline_id_(AnimationIdProvider::NextTimelineId()),
-        player_id_(AnimationIdProvider::NextPlayerId()),
-        player_child_id_(AnimationIdProvider::NextPlayerId()) {
-    timeline_ = AnimationTimeline::Create(timeline_id_);
-    player_ = AnimationPlayer::Create(player_id_);
-    player_child_ = AnimationPlayer::Create(player_child_id_);
-
-    player_->set_layer_animation_delegate(this);
-  }
-
-  void InitializeSettings(LayerTreeSettings* settings) override {
-    settings->use_compositor_animation_timelines = true;
-  }
-
-  void InitializeLayerSettings(LayerSettings* layer_settings) override {
-    layer_settings->use_compositor_animation_timelines = true;
-  }
-
-  void SetupTree() override { LayerTreeTest::SetupTree(); }
-
-  void AttachPlayersToTimeline() {
-    layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get());
-    timeline_->AttachPlayer(player_.get());
-    timeline_->AttachPlayer(player_child_.get());
-  }
-
- protected:
-  scoped_refptr<AnimationTimeline> timeline_;
-  scoped_refptr<AnimationPlayer> player_;
-  scoped_refptr<AnimationPlayer> player_child_;
-
-  const int timeline_id_;
-  const int player_id_;
-  const int player_child_id_;
-};
-
-// Add a layer animation and confirm that
-// LayerTreeHostImpl::UpdateAnimationState does get called.
-// Evolved from LayerTreeHostAnimationTestAddAnimation
-class LayerTreeHostTimelinesTestAddAnimation
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestAddAnimation()
-      : update_animation_state_was_called_(false) {}
-
-  void BeginTest() override {
-    AttachPlayersToTimeline();
-    player_->AttachLayer(layer_tree_host()->root_layer()->id());
-    PostAddInstantAnimationToMainThreadPlayer(player_.get());
-  }
-
-  void UpdateAnimationState(LayerTreeHostImpl* host_impl,
-                            bool has_unfinished_animation) override {
-    EXPECT_FALSE(has_unfinished_animation);
-    update_animation_state_was_called_ = true;
-  }
-
-  void NotifyAnimationStarted(base::TimeTicks monotonic_time,
-                              TargetProperty::Type target_property,
-                              int group) override {
-    EXPECT_LT(base::TimeTicks(), monotonic_time);
-
-    LayerAnimationController* controller =
-        player_->element_animations()->layer_animation_controller();
-    Animation* animation = controller->GetAnimation(TargetProperty::OPACITY);
-    if (animation)
-      player_->RemoveAnimation(animation->id());
-
-    EndTest();
-  }
-
-  void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); }
-
- private:
-  bool update_animation_state_was_called_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAddAnimation);
-
-// Add a layer animation to a layer, but continually fail to draw. Confirm that
-// after a while, we do eventually force a draw.
-// Evolved from LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws.
-class LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws()
-      : started_animating_(false) {}
-
-  void BeginTest() override {
-    AttachPlayersToTimeline();
-    player_->AttachLayer(layer_tree_host()->root_layer()->id());
-    PostAddAnimationToMainThreadPlayer(player_.get());
-  }
-
-  void AnimateLayers(LayerTreeHostImpl* host_impl,
-                     base::TimeTicks monotonic_time) override {
-    started_animating_ = true;
-  }
-
-  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
-    if (started_animating_)
-      EndTest();
-  }
-
-  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
-                                   LayerTreeHostImpl::FrameData* frame,
-                                   DrawResult draw_result) override {
-    return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
-  }
-
-  void AfterTest() override {}
-
- private:
-  bool started_animating_;
-};
-
-// Starvation can only be an issue with the MT compositor.
-MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws);
-
-// Ensures that animations eventually get deleted.
-// Evolved from LayerTreeHostAnimationTestAnimationsGetDeleted.
-class LayerTreeHostTimelinesTestAnimationsGetDeleted
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestAnimationsGetDeleted()
-      : started_animating_(false) {}
-
-  void BeginTest() override {
-    AttachPlayersToTimeline();
-    player_->AttachLayer(layer_tree_host()->root_layer()->id());
-    PostAddAnimationToMainThreadPlayer(player_.get());
-  }
-
-  void AnimateLayers(LayerTreeHostImpl* host_impl,
-                     base::TimeTicks monotonic_time) override {
-    bool have_animations = !host_impl->animation_host()
-                                ->animation_registrar()
-                                ->active_animation_controllers_for_testing()
-                                .empty();
-    if (!started_animating_ && have_animations) {
-      started_animating_ = true;
-      return;
-    }
-
-    if (started_animating_ && !have_animations)
-      EndTest();
-  }
-
-  void NotifyAnimationFinished(base::TimeTicks monotonic_time,
-                               TargetProperty::Type target_property,
-                               int group) override {
-    // Animations on the impl-side controller only get deleted during a commit,
-    // so we need to schedule a commit.
-    layer_tree_host()->SetNeedsCommit();
-  }
-
-  void AfterTest() override {}
-
- private:
-  bool started_animating_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationsGetDeleted);
-
-// Ensure that an animation's timing function is respected.
-// Evolved from LayerTreeHostAnimationTestAddAnimationWithTimingFunction.
-class LayerTreeHostTimelinesTestAddAnimationWithTimingFunction
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestAddAnimationWithTimingFunction() {}
-
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-    picture_ = FakePictureLayer::Create(layer_settings(), &client_);
-    picture_->SetBounds(gfx::Size(4, 4));
-    client_.set_bounds(picture_->bounds());
-    layer_tree_host()->root_layer()->AddChild(picture_);
-
-    AttachPlayersToTimeline();
-    player_child_->AttachLayer(picture_->id());
-  }
-
-  void BeginTest() override {
-    PostAddAnimationToMainThreadPlayer(player_child_.get());
-  }
-
-  void AnimateLayers(LayerTreeHostImpl* host_impl,
-                     base::TimeTicks monotonic_time) override {
-    // Wait for the commit with the animation to happen.
-    if (host_impl->sync_tree()->source_frame_number() != 0)
-      return;
-
-    scoped_refptr<AnimationTimeline> timeline_impl =
-        host_impl->animation_host()->GetTimelineById(timeline_id_);
-    scoped_refptr<AnimationPlayer> player_child_impl =
-        timeline_impl->GetPlayerById(player_child_id_);
-
-    LayerAnimationController* controller_impl =
-        player_child_impl->element_animations()->layer_animation_controller();
-    Animation* animation =
-        controller_impl->GetAnimation(TargetProperty::OPACITY);
-
-    const FloatAnimationCurve* curve =
-        animation->curve()->ToFloatAnimationCurve();
-    float start_opacity = curve->GetValue(base::TimeDelta());
-    float end_opacity = curve->GetValue(curve->Duration());
-    float linearly_interpolated_opacity =
-        0.25f * end_opacity + 0.75f * start_opacity;
-    base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f);
-    // If the linear timing function associated with this animation was not
-    // picked up, then the linearly interpolated opacity would be different
-    // because of the default ease timing function.
-    EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
-
-    EndTest();
-  }
-
-  void AfterTest() override {}
-
-  FakeContentLayerClient client_;
-  scoped_refptr<FakePictureLayer> picture_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestAddAnimationWithTimingFunction);
-
-// Ensures that main thread animations have their start times synchronized with
-// impl thread animations.
-// Evolved from LayerTreeHostAnimationTestSynchronizeAnimationStartTimes.
-class LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes() {}
-
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-    picture_ = FakePictureLayer::Create(layer_settings(), &client_);
-    picture_->SetBounds(gfx::Size(4, 4));
-    client_.set_bounds(picture_->bounds());
-
-    layer_tree_host()->root_layer()->AddChild(picture_);
-
-    AttachPlayersToTimeline();
-    player_child_->set_layer_animation_delegate(this);
-    player_child_->AttachLayer(picture_->id());
-  }
-
-  void BeginTest() override {
-    PostAddAnimationToMainThreadPlayer(player_child_.get());
-  }
-
-  void NotifyAnimationStarted(base::TimeTicks monotonic_time,
-                              TargetProperty::Type target_property,
-                              int group) override {
-    LayerAnimationController* controller =
-        player_child_->element_animations()->layer_animation_controller();
-    Animation* animation = controller->GetAnimation(TargetProperty::OPACITY);
-    main_start_time_ = animation->start_time();
-    controller->RemoveAnimation(animation->id());
-    EndTest();
-  }
-
-  void UpdateAnimationState(LayerTreeHostImpl* impl_host,
-                            bool has_unfinished_animation) override {
-    scoped_refptr<AnimationTimeline> timeline_impl =
-        impl_host->animation_host()->GetTimelineById(timeline_id_);
-    scoped_refptr<AnimationPlayer> player_child_impl =
-        timeline_impl->GetPlayerById(player_child_id_);
-
-    LayerAnimationController* controller =
-        player_child_impl->element_animations()->layer_animation_controller();
-    Animation* animation = controller->GetAnimation(TargetProperty::OPACITY);
-    if (!animation)
-      return;
-
-    impl_start_time_ = animation->start_time();
-  }
-
-  void AfterTest() override {
-    EXPECT_EQ(impl_start_time_, main_start_time_);
-    EXPECT_LT(base::TimeTicks(), impl_start_time_);
-  }
-
- private:
-  base::TimeTicks main_start_time_;
-  base::TimeTicks impl_start_time_;
-  FakeContentLayerClient client_;
-  scoped_refptr<FakePictureLayer> picture_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes);
-
-// Ensures that notify animation finished is called.
-// Evolved from LayerTreeHostAnimationTestAnimationFinishedEvents.
-class LayerTreeHostTimelinesTestAnimationFinishedEvents
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestAnimationFinishedEvents() {}
-
-  void BeginTest() override {
-    AttachPlayersToTimeline();
-    player_->AttachLayer(layer_tree_host()->root_layer()->id());
-    PostAddInstantAnimationToMainThreadPlayer(player_.get());
-  }
-
-  void NotifyAnimationFinished(base::TimeTicks monotonic_time,
-                               TargetProperty::Type target_property,
-                               int group) override {
-    LayerAnimationController* controller =
-        player_->element_animations()->layer_animation_controller();
-    Animation* animation = controller->GetAnimation(TargetProperty::OPACITY);
-    if (animation)
-      controller->RemoveAnimation(animation->id());
-    EndTest();
-  }
-
-  void AfterTest() override {}
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestAnimationFinishedEvents);
-
-// Ensures that when opacity is being animated, this value does not cause the
-// subtree to be skipped.
-// Evolved from LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity.
-class LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity()
-      : update_check_layer_(
-            FakePictureLayer::Create(layer_settings(), &client_)) {}
-
-  void SetupTree() override {
-    update_check_layer_->SetOpacity(0.f);
-    layer_tree_host()->SetRootLayer(update_check_layer_);
-    client_.set_bounds(update_check_layer_->bounds());
-    LayerTreeHostTimelinesTest::SetupTree();
-
-    AttachPlayersToTimeline();
-    player_->AttachLayer(update_check_layer_->id());
-  }
-
-  void BeginTest() override {
-    PostAddAnimationToMainThreadPlayer(player_.get());
-  }
-
-  void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
-    scoped_refptr<AnimationTimeline> timeline_impl =
-        host_impl->animation_host()->GetTimelineById(timeline_id_);
-    scoped_refptr<AnimationPlayer> player_impl =
-        timeline_impl->GetPlayerById(player_id_);
-
-    LayerAnimationController* controller_impl =
-        player_impl->element_animations()->layer_animation_controller();
-    Animation* animation_impl =
-        controller_impl->GetAnimation(TargetProperty::OPACITY);
-    controller_impl->RemoveAnimation(animation_impl->id());
-    EndTest();
-  }
-
-  void AfterTest() override {
-    // Update() should have been called once, proving that the layer was not
-    // skipped.
-    EXPECT_EQ(1, update_check_layer_->update_count());
-
-    // clear update_check_layer_ so LayerTreeHost dies.
-    update_check_layer_ = NULL;
-  }
-
- private:
-  FakeContentLayerClient client_;
-  scoped_refptr<FakePictureLayer> update_check_layer_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity);
-
-// Layers added to tree with existing active animations should have the
-// animation correctly recognized.
-// Evolved from LayerTreeHostAnimationTestLayerAddedWithAnimation.
-class LayerTreeHostTimelinesTestLayerAddedWithAnimation
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestLayerAddedWithAnimation() {}
-
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void DidCommit() override {
-    if (layer_tree_host()->source_frame_number() == 1) {
-      AttachPlayersToTimeline();
-
-      scoped_refptr<Layer> layer = Layer::Create(layer_settings());
-      player_->AttachLayer(layer->id());
-      player_->set_layer_animation_delegate(this);
-
-      // Any valid AnimationCurve will do here.
-      scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
-      scoped_ptr<Animation> animation(
-          Animation::Create(std::move(curve), 1, 1, TargetProperty::OPACITY));
-      player_->AddAnimation(std::move(animation));
-
-      // We add the animation *before* attaching the layer to the tree.
-      layer_tree_host()->root_layer()->AddChild(layer);
-    }
-  }
-
-  void AnimateLayers(LayerTreeHostImpl* impl_host,
-                     base::TimeTicks monotonic_time) override {
-    EndTest();
-  }
-
-  void AfterTest() override {}
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestLayerAddedWithAnimation);
-
-// Animations should not be started when frames are being skipped due to
-// checkerboard.
-// Evolved from LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations.
-class LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations
-    : public LayerTreeHostTimelinesTest {
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-    picture_ = FakePictureLayer::Create(layer_settings(), &client_);
-    picture_->SetBounds(gfx::Size(4, 4));
-    client_.set_bounds(picture_->bounds());
-    layer_tree_host()->root_layer()->AddChild(picture_);
-
-    AttachPlayersToTimeline();
-    player_child_->AttachLayer(picture_->id());
-    player_child_->set_layer_animation_delegate(this);
-  }
-
-  void InitializeSettings(LayerTreeSettings* settings) override {
-    // Make sure that drawing many times doesn't cause a checkerboarded
-    // animation to start so we avoid flake in this test.
-    settings->timeout_and_draw_when_animation_checkerboards = false;
-    LayerTreeHostTimelinesTest::InitializeSettings(settings);
-  }
-
-  void BeginTest() override {
-    prevented_draw_ = 0;
-    started_times_ = 0;
-
-    PostSetNeedsCommitToMainThread();
-  }
-
-  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
-                                   LayerTreeHostImpl::FrameData* frame_data,
-                                   DrawResult draw_result) override {
-    // Don't checkerboard when the first animation wants to start.
-    if (host_impl->active_tree()->source_frame_number() < 2)
-      return draw_result;
-    if (TestEnded())
-      return draw_result;
-    // Act like there is checkerboard when the second animation wants to draw.
-    ++prevented_draw_;
-    if (prevented_draw_ > 2)
-      EndTest();
-    return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
-  }
-
-  void DidCommitAndDrawFrame() override {
-    switch (layer_tree_host()->source_frame_number()) {
-      case 1:
-        // The animation is longer than 1 BeginFrame interval.
-        AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 0.2f, 0.8f,
-                                     false);
-        break;
-      case 2:
-        // This second animation will not be drawn so it should not start.
-        AddAnimatedTransformToPlayer(player_child_.get(), 0.1, 5, 5);
-        break;
-    }
-  }
-
-  void NotifyAnimationStarted(base::TimeTicks monotonic_time,
-                              TargetProperty::Type target_property,
-                              int group) override {
-    if (TestEnded())
-      return;
-    started_times_++;
-  }
-
-  void AfterTest() override {
-    // Make sure we tried to draw the second animation but failed.
-    EXPECT_LT(0, prevented_draw_);
-    // The first animation should be started, but the second should not because
-    // of checkerboard.
-    EXPECT_EQ(1, started_times_);
-  }
-
-  int prevented_draw_;
-  int started_times_;
-  FakeContentLayerClient client_;
-  scoped_refptr<FakePictureLayer> picture_;
-};
-
-MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations);
-
-// Verifies that scroll offset animations are only accepted when impl-scrolling
-// is supported, and that when scroll offset animations are accepted,
-// scroll offset updates are sent back to the main thread.
-// Evolved from LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
-class LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated() {}
-
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-
-    scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
-    scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
-    scroll_layer_->SetBounds(gfx::Size(1000, 1000));
-    client_.set_bounds(scroll_layer_->bounds());
-    scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
-    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
-
-    AttachPlayersToTimeline();
-    player_child_->AttachLayer(scroll_layer_->id());
-  }
-
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void DidCommit() override {
-    switch (layer_tree_host()->source_frame_number()) {
-      case 1: {
-        scoped_ptr<ScrollOffsetAnimationCurve> curve(
-            ScrollOffsetAnimationCurve::Create(
-                gfx::ScrollOffset(500.f, 550.f),
-                EaseInOutTimingFunction::Create()));
-        scoped_ptr<Animation> animation(Animation::Create(
-            std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
-        animation->set_needs_synchronized_start_time(true);
-        bool impl_scrolling_supported =
-            layer_tree_host()->proxy()->SupportsImplScrolling();
-        if (impl_scrolling_supported)
-          player_child_->AddAnimation(std::move(animation));
-        else
-          EndTest();
-        break;
-      }
-      default:
-        if (scroll_layer_->scroll_offset().x() > 10 &&
-            scroll_layer_->scroll_offset().y() > 20)
-          EndTest();
-    }
-  }
-
-  void AfterTest() override {}
-
- private:
-  FakeContentLayerClient client_;
-  scoped_refptr<FakePictureLayer> scroll_layer_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated);
-
-// Verifies that when the main thread removes a scroll animation and sets a new
-// scroll position, the active tree takes on exactly this new scroll position
-// after activation, and the main thread doesn't receive a spurious scroll
-// delta.
-// Evolved from LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
-class LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval()
-      : final_postion_(50.0, 100.0) {}
-
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-
-    scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
-    scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
-    scroll_layer_->SetBounds(gfx::Size(10000, 10000));
-    client_.set_bounds(scroll_layer_->bounds());
-    scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
-    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
-
-    scoped_ptr<ScrollOffsetAnimationCurve> curve(
-        ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f),
-                                           EaseInOutTimingFunction::Create()));
-    scoped_ptr<Animation> animation(Animation::Create(
-        std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
-    animation->set_needs_synchronized_start_time(true);
-
-    AttachPlayersToTimeline();
-    player_child_->AttachLayer(scroll_layer_->id());
-    player_child_->AddAnimation(std::move(animation));
-  }
-
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void BeginMainFrame(const BeginFrameArgs& args) override {
-    switch (layer_tree_host()->source_frame_number()) {
-      case 0:
-        break;
-      case 1: {
-        Animation* animation =
-            player_child_->element_animations()
-                ->layer_animation_controller()
-                ->GetAnimation(TargetProperty::SCROLL_OFFSET);
-        player_child_->RemoveAnimation(animation->id());
-        scroll_layer_->SetScrollOffset(final_postion_);
-        break;
-      }
-      default:
-        EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
-    }
-  }
-
-  void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
-    host_impl->BlockNotifyReadyToActivateForTesting(true);
-  }
-
-  void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
-                                  const BeginFrameArgs& args) override {
-    if (!host_impl->pending_tree())
-      return;
-
-    if (!host_impl->active_tree()->root_layer()) {
-      host_impl->BlockNotifyReadyToActivateForTesting(false);
-      return;
-    }
-
-    scoped_refptr<AnimationTimeline> timeline_impl =
-        host_impl->animation_host()->GetTimelineById(timeline_id_);
-    scoped_refptr<AnimationPlayer> player_impl =
-        timeline_impl->GetPlayerById(player_child_id_);
-
-    LayerImpl* scroll_layer_impl =
-        host_impl->active_tree()->root_layer()->children()[0].get();
-    Animation* animation = player_impl->element_animations()
-                               ->layer_animation_controller()
-                               ->GetAnimation(TargetProperty::SCROLL_OFFSET);
-
-    if (!animation || animation->run_state() != Animation::RUNNING) {
-      host_impl->BlockNotifyReadyToActivateForTesting(false);
-      return;
-    }
-
-    // Block activation until the running animation has a chance to produce a
-    // scroll delta.
-    gfx::Vector2dF scroll_delta = ScrollDelta(scroll_layer_impl);
-    if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f)
-      return;
-
-    host_impl->BlockNotifyReadyToActivateForTesting(false);
-  }
-
-  void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
-    if (host_impl->pending_tree()->source_frame_number() != 1)
-      return;
-    LayerImpl* scroll_layer_impl =
-        host_impl->pending_tree()->root_layer()->children()[0].get();
-    EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
-  }
-
-  void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
-    if (host_impl->active_tree()->source_frame_number() != 1)
-      return;
-    LayerImpl* scroll_layer_impl =
-        host_impl->active_tree()->root_layer()->children()[0].get();
-    EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
-    EndTest();
-  }
-
-  void AfterTest() override {
-    EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
-  }
-
- private:
-  FakeContentLayerClient client_;
-  scoped_refptr<FakePictureLayer> scroll_layer_;
-  const gfx::ScrollOffset final_postion_;
-};
-
-MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval);
-
-// When animations are simultaneously added to an existing layer and to a new
-// layer, they should start at the same time, even when there's already a
-// running animation on the existing layer.
-// Evolved from LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers.
-class LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers()
-      : frame_count_with_pending_tree_(0) {}
-
-  void BeginTest() override {
-    AttachPlayersToTimeline();
-    PostSetNeedsCommitToMainThread();
-  }
-
-  void DidCommit() override {
-    if (layer_tree_host()->source_frame_number() == 1) {
-      player_->AttachLayer(layer_tree_host()->root_layer()->id());
-      AddAnimatedTransformToPlayer(player_.get(), 4, 1, 1);
-    } else if (layer_tree_host()->source_frame_number() == 2) {
-      AddOpacityTransitionToPlayer(player_.get(), 1, 0.f, 0.5f, true);
-
-      scoped_refptr<Layer> layer = Layer::Create(layer_settings());
-      layer_tree_host()->root_layer()->AddChild(layer);
-      layer->SetBounds(gfx::Size(4, 4));
-
-      player_child_->AttachLayer(layer->id());
-      player_child_->set_layer_animation_delegate(this);
-      AddOpacityTransitionToPlayer(player_child_.get(), 1, 0.f, 0.5f, true);
-    }
-  }
-
-  void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
-    host_impl->BlockNotifyReadyToActivateForTesting(true);
-  }
-
-  void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
-    // For the commit that added animations to new and existing layers, keep
-    // blocking activation. We want to verify that even with activation blocked,
-    // the animation on the layer that's already in the active tree won't get a
-    // head start.
-    if (host_impl->pending_tree()->source_frame_number() != 2) {
-      host_impl->BlockNotifyReadyToActivateForTesting(false);
-    }
-  }
-
-  void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
-                                  const BeginFrameArgs& args) override {
-    if (!host_impl->pending_tree() ||
-        host_impl->pending_tree()->source_frame_number() != 2)
-      return;
-
-    frame_count_with_pending_tree_++;
-    if (frame_count_with_pending_tree_ == 2) {
-      host_impl->BlockNotifyReadyToActivateForTesting(false);
-    }
-  }
-
-  void UpdateAnimationState(LayerTreeHostImpl* host_impl,
-                            bool has_unfinished_animation) override {
-    scoped_refptr<AnimationTimeline> timeline_impl =
-        host_impl->animation_host()->GetTimelineById(timeline_id_);
-    scoped_refptr<AnimationPlayer> player_impl =
-        timeline_impl->GetPlayerById(player_id_);
-    scoped_refptr<AnimationPlayer> player_child_impl =
-        timeline_impl->GetPlayerById(player_child_id_);
-
-    // wait for tree activation.
-    if (!player_impl->element_animations())
-      return;
-
-    LayerAnimationController* root_controller_impl =
-        player_impl->element_animations()->layer_animation_controller();
-    Animation* root_animation =
-        root_controller_impl->GetAnimation(TargetProperty::OPACITY);
-    if (!root_animation || root_animation->run_state() != Animation::RUNNING)
-      return;
-
-    LayerAnimationController* child_controller_impl =
-        player_child_impl->element_animations()->layer_animation_controller();
-    Animation* child_animation =
-        child_controller_impl->GetAnimation(TargetProperty::OPACITY);
-    EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
-    EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
-    root_controller_impl->AbortAnimations(TargetProperty::OPACITY);
-    root_controller_impl->AbortAnimations(TargetProperty::TRANSFORM);
-    child_controller_impl->AbortAnimations(TargetProperty::OPACITY);
-    EndTest();
-  }
-
-  void AfterTest() override {}
-
- private:
-  int frame_count_with_pending_tree_;
-};
-
-// This test blocks activation which is not supported for single thread mode.
-MULTI_THREAD_BLOCKNOTIFY_TEST_F(
-    LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers);
-
-// Evolved from LayerTreeHostAnimationTestAddAnimationAfterAnimating.
-class LayerTreeHostTimelinesTestAddAnimationAfterAnimating
-    : public LayerTreeHostTimelinesTest {
- public:
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-    content_ = Layer::Create(layer_settings());
-    content_->SetBounds(gfx::Size(4, 4));
-    layer_tree_host()->root_layer()->AddChild(content_);
-
-    AttachPlayersToTimeline();
-
-    player_->AttachLayer(layer_tree_host()->root_layer()->id());
-    player_child_->AttachLayer(content_->id());
-  }
-
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void DidCommit() override {
-    switch (layer_tree_host()->source_frame_number()) {
-      case 1:
-        // First frame: add an animation to the root layer.
-        AddAnimatedTransformToPlayer(player_.get(), 0.1, 5, 5);
-        break;
-      case 2:
-        // Second frame: add an animation to the content layer. The root layer
-        // animation has caused us to animate already during this frame.
-        AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 5, 5, false);
-        break;
-    }
-  }
-
-  void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
-    // After both animations have started, verify that they have valid
-    // start times.
-    if (host_impl->active_tree()->source_frame_number() < 2)
-      return;
-    AnimationRegistrar::AnimationControllerMap controllers_copy =
-        host_impl->animation_host()
-            ->animation_registrar()
-            ->active_animation_controllers_for_testing();
-    EXPECT_EQ(2u, controllers_copy.size());
-    for (auto& it : controllers_copy) {
-      int id = it.first;
-      if (id == host_impl->RootLayer()->id()) {
-        Animation* anim = it.second->GetAnimation(TargetProperty::TRANSFORM);
-        EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
-      } else if (id == host_impl->RootLayer()->children()[0]->id()) {
-        Animation* anim = it.second->GetAnimation(TargetProperty::OPACITY);
-        EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
-      }
-      EndTest();
-    }
-  }
-
-  void AfterTest() override {}
-
- private:
-  scoped_refptr<Layer> content_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestAddAnimationAfterAnimating);
-
-class LayerTreeHostTimelinesTestRemoveAnimation
-    : public LayerTreeHostTimelinesTest {
- public:
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-    layer_ = FakePictureLayer::Create(layer_settings(), &client_);
-    layer_->SetBounds(gfx::Size(4, 4));
-    client_.set_bounds(layer_->bounds());
-    layer_tree_host()->root_layer()->AddChild(layer_);
-
-    AttachPlayersToTimeline();
-
-    player_->AttachLayer(layer_tree_host()->root_layer()->id());
-    player_child_->AttachLayer(layer_->id());
-  }
-
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void DidCommit() override {
-    switch (layer_tree_host()->source_frame_number()) {
-      case 1:
-        AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5);
-        break;
-      case 2:
-        LayerAnimationController* controller =
-            player_child_->element_animations()->layer_animation_controller();
-        Animation* animation =
-            controller->GetAnimation(TargetProperty::TRANSFORM);
-        player_child_->RemoveAnimation(animation->id());
-        gfx::Transform transform;
-        transform.Translate(10.f, 10.f);
-        layer_->SetTransform(transform);
-
-        // Do something that causes property trees to get rebuilt.
-        layer_->AddChild(Layer::Create(layer_settings()));
-        break;
-    }
-  }
-
-  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
-    if (host_impl->active_tree()->source_frame_number() < 2)
-      return;
-    gfx::Transform expected_transform;
-    expected_transform.Translate(10.f, 10.f);
-    EXPECT_EQ(
-        expected_transform,
-        host_impl->active_tree()->root_layer()->children()[0]->DrawTransform());
-    EndTest();
-  }
-
-  void AfterTest() override {}
-
- private:
-  scoped_refptr<Layer> layer_;
-  FakeContentLayerClient client_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestRemoveAnimation);
-
-class LayerTreeHostTimelinesTestAnimationFinishesDuringCommit
-    : public LayerTreeHostTimelinesTest {
- public:
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-    layer_ = FakePictureLayer::Create(layer_settings(), &client_);
-    layer_->SetBounds(gfx::Size(4, 4));
-    client_.set_bounds(layer_->bounds());
-    layer_tree_host()->root_layer()->AddChild(layer_);
-
-    AttachPlayersToTimeline();
-
-    player_->AttachLayer(layer_tree_host()->root_layer()->id());
-    player_child_->AttachLayer(layer_->id());
-  }
-
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void DidCommit() override {
-    if (layer_tree_host()->source_frame_number() == 1)
-      AddAnimatedTransformToPlayer(player_child_.get(), 0.04, 5, 5);
-  }
-
-  void WillCommit() override {
-    if (layer_tree_host()->source_frame_number() == 2) {
-      // Block until the animation finishes on the compositor thread. Since
-      // animations have already been ticked on the main thread, when the commit
-      // happens the state on the main thread will be consistent with having a
-      // running animation but the state on the compositor thread will be
-      // consistent with having only a finished animation.
-      completion_.Wait();
-    }
-  }
-
-  void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
-    switch (host_impl->sync_tree()->source_frame_number()) {
-      case 1:
-        PostSetNeedsCommitToMainThread();
-        break;
-      case 2:
-        gfx::Transform expected_transform;
-        expected_transform.Translate(5.f, 5.f);
-        LayerImpl* layer_impl =
-            host_impl->sync_tree()->root_layer()->children()[0].get();
-        EXPECT_EQ(expected_transform, layer_impl->DrawTransform());
-        EndTest();
-        break;
-    }
-  }
-
-  void UpdateAnimationState(LayerTreeHostImpl* host_impl,
-                            bool has_unfinished_animation) override {
-    if (host_impl->active_tree()->source_frame_number() == 1 &&
-        !has_unfinished_animation) {
-      // The animation has finished, so allow the main thread to commit.
-      completion_.Signal();
-    }
-  }
-
-  void AfterTest() override {}
-
- private:
-  scoped_refptr<Layer> layer_;
-  FakeContentLayerClient client_;
-  CompletionEvent completion_;
-};
-
-// An animation finishing during commit can only happen when we have a separate
-// compositor thread.
-MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationFinishesDuringCommit);
-
-// Check that SetTransformIsPotentiallyAnimatingChanged is called
-// if we destroy LayerAnimationController and ElementAnimations.
-class LayerTreeHostTimelinesTestSetPotentiallyAnimatingOnLacDestruction
-    : public LayerTreeHostTimelinesTest {
- public:
-  void SetupTree() override {
-    prev_screen_space_transform_is_animating_ = true;
-    screen_space_transform_animation_stopped_ = false;
-
-    LayerTreeHostTimelinesTest::SetupTree();
-    AttachPlayersToTimeline();
-    player_->AttachLayer(layer_tree_host()->root_layer()->id());
-    AddAnimatedTransformToPlayer(player_.get(), 1.0, 5, 5);
-  }
-
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
-    if (host_impl->pending_tree()->source_frame_number() <= 1) {
-      EXPECT_TRUE(host_impl->pending_tree()
-                      ->root_layer()
-                      ->screen_space_transform_is_animating());
-    } else {
-      EXPECT_FALSE(host_impl->pending_tree()
-                       ->root_layer()
-                       ->screen_space_transform_is_animating());
-    }
-  }
-
-  void DidCommit() override { PostSetNeedsCommitToMainThread(); }
-
-  void UpdateLayerTreeHost() override {
-    if (layer_tree_host()->source_frame_number() == 2) {
-      // Destroy player.
-      timeline_->DetachPlayer(player_.get());
-      player_ = nullptr;
-    }
-  }
-
-  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
-                                   LayerTreeHostImpl::FrameData* frame_data,
-                                   DrawResult draw_result) override {
-    const bool screen_space_transform_is_animating =
-        host_impl->active_tree()
-            ->root_layer()
-            ->screen_space_transform_is_animating();
-
-    // Check that screen_space_transform_is_animating changes only once.
-    if (screen_space_transform_is_animating &&
-        prev_screen_space_transform_is_animating_)
-      EXPECT_FALSE(screen_space_transform_animation_stopped_);
-    if (!screen_space_transform_is_animating &&
-        prev_screen_space_transform_is_animating_) {
-      EXPECT_FALSE(screen_space_transform_animation_stopped_);
-      screen_space_transform_animation_stopped_ = true;
-    }
-    if (!screen_space_transform_is_animating &&
-        !prev_screen_space_transform_is_animating_)
-      EXPECT_TRUE(screen_space_transform_animation_stopped_);
-
-    prev_screen_space_transform_is_animating_ =
-        screen_space_transform_is_animating;
-
-    return draw_result;
-  }
-
-  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
-    if (host_impl->active_tree()->source_frame_number() >= 2)
-      EndTest();
-  }
-
-  void AfterTest() override {
-    EXPECT_TRUE(screen_space_transform_animation_stopped_);
-  }
-
-  bool prev_screen_space_transform_is_animating_;
-  bool screen_space_transform_animation_stopped_;
-};
-
-MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestSetPotentiallyAnimatingOnLacDestruction);
-
-// Check that we invalidate property trees on AnimationPlayer::SetNeedsCommit.
-class LayerTreeHostTimelinesTestRebuildPropertyTreesOnAnimationSetNeedsCommit
-    : public LayerTreeHostTimelinesTest {
- public:
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-    layer_ = FakePictureLayer::Create(layer_settings(), &client_);
-    layer_->SetBounds(gfx::Size(4, 4));
-    client_.set_bounds(layer_->bounds());
-    layer_tree_host()->root_layer()->AddChild(layer_);
-
-    AttachPlayersToTimeline();
-
-    player_->AttachLayer(layer_tree_host()->root_layer()->id());
-    player_child_->AttachLayer(layer_->id());
-  }
-
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void DidCommit() override {
-    if (layer_tree_host()->source_frame_number() == 1 ||
-        layer_tree_host()->source_frame_number() == 2)
-      PostSetNeedsCommitToMainThread();
-  }
-
-  void UpdateLayerTreeHost() override {
-    if (layer_tree_host()->source_frame_number() == 1) {
-      EXPECT_FALSE(layer_tree_host()->property_trees()->needs_rebuild);
-      AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5);
-    }
-
-    EXPECT_TRUE(layer_tree_host()->property_trees()->needs_rebuild);
-  }
-
-  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
-    if (host_impl->active_tree()->source_frame_number() >= 2)
-      EndTest();
-  }
-
-  void AfterTest() override {}
-
- private:
-  scoped_refptr<Layer> layer_;
-  FakeContentLayerClient client_;
-};
-
-MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestRebuildPropertyTreesOnAnimationSetNeedsCommit);
-
-class LayerTreeHostTimelinesTestPendingTreeAnimatesFirstCommit
-    : public LayerTreeHostTimelinesTest {
- public:
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-
-    layer_ = FakePictureLayer::Create(layer_settings(), &client_);
-    layer_->SetBounds(gfx::Size(2, 2));
-    client_.set_bounds(layer_->bounds());
-    // Transform the layer to 4,4 to start.
-    gfx::Transform start_transform;
-    start_transform.Translate(4.0, 4.0);
-    layer_->SetTransform(start_transform);
-
-    layer_tree_host()->root_layer()->AddChild(layer_);
-    player_->AttachLayer(layer_->id());
-
-    AttachPlayersToTimeline();
-  }
-
-  void BeginTest() override {
-    // Add a translate from 6,7 to 8,9.
-    TransformOperations start;
-    start.AppendTranslate(6.f, 7.f, 0.f);
-    TransformOperations end;
-    end.AppendTranslate(8.f, 9.f, 0.f);
-    AddAnimatedTransformToPlayer(player_.get(), 4.0, start, end);
-
-    PostSetNeedsCommitToMainThread();
-  }
-
-  void WillPrepareTiles(LayerTreeHostImpl* host_impl) override {
-    if (host_impl->sync_tree()->source_frame_number() != 0)
-      return;
-
-    // After checking this on the sync tree, we will activate, which will cause
-    // PrepareTiles to happen again (which races with the test exiting).
-    if (TestEnded())
-      return;
-
-    scoped_refptr<AnimationTimeline> timeline_impl =
-        host_impl->animation_host()->GetTimelineById(timeline_id_);
-    scoped_refptr<AnimationPlayer> player_impl =
-        timeline_impl->GetPlayerById(player_id_);
-
-    LayerAnimationController* controller_impl =
-        player_impl->element_animations()->layer_animation_controller();
-
-    LayerImpl* root = host_impl->sync_tree()->root_layer();
-    LayerImpl* child = root->children()[0].get();
-    Animation* animation =
-        controller_impl->GetAnimation(TargetProperty::TRANSFORM);
-
-    // The animation should be starting for the first frame.
-    EXPECT_EQ(Animation::STARTING, animation->run_state());
-
-    // And the transform should be propogated to the sync tree layer, at its
-    // starting state which is 6,7.
-    gfx::Transform expected_transform;
-    expected_transform.Translate(6.0, 7.0);
-    EXPECT_EQ(expected_transform, child->DrawTransform());
-    // And the sync tree layer should know it is animating.
-    EXPECT_TRUE(child->screen_space_transform_is_animating());
-
-    controller_impl->AbortAnimations(TargetProperty::TRANSFORM);
-    EndTest();
-  }
-
-  void AfterTest() override {}
-
-  FakeContentLayerClient client_;
-  scoped_refptr<Layer> layer_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestPendingTreeAnimatesFirstCommit);
-
-// When a layer with an animation is removed from the tree and later re-added,
-// the animation should resume.
-class LayerTreeHostTimelinesTestAnimatedLayerRemovedAndAdded
-    : public LayerTreeHostTimelinesTest {
- public:
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-    layer_ = Layer::Create(layer_settings());
-    layer_->SetBounds(gfx::Size(4, 4));
-    layer_tree_host()->root_layer()->AddChild(layer_);
-
-    layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get());
-    timeline_->AttachPlayer(player_.get());
-    player_->AttachLayer(layer_->id());
-    DCHECK(player_->element_animations());
-
-    AddOpacityTransitionToPlayer(player_.get(), 10000.0, 0.1f, 0.9f, true);
-  }
-
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void DidCommit() override {
-    switch (layer_tree_host()->source_frame_number()) {
-      case 0:
-        EXPECT_TRUE(player_->element_animations()
-                        ->has_active_value_observer_for_testing());
-        EXPECT_FALSE(player_->element_animations()
-                         ->has_pending_value_observer_for_testing());
-        EXPECT_TRUE(layer_tree_host()
-                        ->animation_host()
-                        ->animation_registrar()
-                        ->needs_animate_layers());
-        break;
-      case 1:
-        layer_->RemoveFromParent();
-        EXPECT_FALSE(player_->element_animations()
-                         ->has_active_value_observer_for_testing());
-        EXPECT_FALSE(player_->element_animations()
-                         ->has_pending_value_observer_for_testing());
-        EXPECT_TRUE(layer_tree_host()
-                        ->animation_host()
-                        ->animation_registrar()
-                        ->needs_animate_layers());
-        break;
-      case 2:
-        layer_tree_host()->root_layer()->AddChild(layer_);
-        EXPECT_TRUE(player_->element_animations()
-                        ->has_active_value_observer_for_testing());
-        EXPECT_FALSE(player_->element_animations()
-                         ->has_pending_value_observer_for_testing());
-        EXPECT_TRUE(layer_tree_host()
-                        ->animation_host()
-                        ->animation_registrar()
-                        ->needs_animate_layers());
-        break;
-    }
-  }
-
-  void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
-    scoped_refptr<AnimationTimeline> timeline_impl =
-        host_impl->animation_host()->GetTimelineById(timeline_id_);
-    scoped_refptr<AnimationPlayer> player_impl =
-        timeline_impl->GetPlayerById(player_id_);
-
-    switch (host_impl->active_tree()->source_frame_number()) {
-      case 0:
-        EXPECT_TRUE(player_impl->element_animations()
-                        ->has_active_value_observer_for_testing());
-        EXPECT_TRUE(host_impl->animation_host()
-                        ->animation_registrar()
-                        ->needs_animate_layers());
-        break;
-      case 1:
-        EXPECT_FALSE(player_impl->element_animations()
-                         ->has_active_value_observer_for_testing());
-        EXPECT_TRUE(host_impl->animation_host()
-                        ->animation_registrar()
-                        ->needs_animate_layers());
-        break;
-      case 2:
-        EXPECT_TRUE(player_impl->element_animations()
-                        ->has_active_value_observer_for_testing());
-        EXPECT_TRUE(host_impl->animation_host()
-                        ->animation_registrar()
-                        ->needs_animate_layers());
-        EndTest();
-        break;
-    }
-  }
-
-  void AfterTest() override {}
-
- private:
-  scoped_refptr<Layer> layer_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestAnimatedLayerRemovedAndAdded);
-
-class LayerTreeHostTimelinesTestIsAnimating
-    : public LayerTreeHostTimelinesTest {
- public:
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-    layer_ = FakePictureLayer::Create(layer_settings(), &client_);
-    layer_->SetBounds(gfx::Size(4, 4));
-    client_.set_bounds(layer_->bounds());
-    layer_tree_host()->root_layer()->AddChild(layer_);
-
-    AttachPlayersToTimeline();
-    player_->AttachLayer(layer_->id());
-  }
-
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void DidCommit() override {
-    switch (layer_tree_host()->source_frame_number()) {
-      case 1:
-        AddAnimatedTransformToPlayer(player_.get(), 1.0, 5, 5);
-        break;
-      case 2:
-        LayerAnimationController* controller =
-            player_->element_animations()->layer_animation_controller();
-        Animation* animation =
-            controller->GetAnimation(TargetProperty::TRANSFORM);
-        player_->RemoveAnimation(animation->id());
-        break;
-    }
-  }
-
-  void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
-    LayerImpl* root = host_impl->sync_tree()->root_layer();
-    LayerImpl* child = root->children()[0].get();
-    switch (host_impl->sync_tree()->source_frame_number()) {
-      case 0:
-        // No animation yet.
-        break;
-      case 1:
-        // Animation is started.
-        EXPECT_TRUE(child->screen_space_transform_is_animating());
-        break;
-      case 2:
-        // The animation is removed/stopped.
-        EXPECT_FALSE(child->screen_space_transform_is_animating());
-        EndTest();
-        break;
-      default:
-        NOTREACHED();
-    }
-  }
-
-  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
-    LayerImpl* root = host_impl->active_tree()->root_layer();
-    LayerImpl* child = root->children()[0].get();
-    switch (host_impl->active_tree()->source_frame_number()) {
-      case 0:
-        // No animation yet.
-        break;
-      case 1:
-        // Animation is started.
-        EXPECT_TRUE(child->screen_space_transform_is_animating());
-        break;
-      case 2:
-        // The animation is removed/stopped.
-        EXPECT_FALSE(child->screen_space_transform_is_animating());
-        EndTest();
-        break;
-      default:
-        NOTREACHED();
-    }
-  }
-
-  void AfterTest() override {}
-
- private:
-  scoped_refptr<Layer> layer_;
-  FakeContentLayerClient client_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestIsAnimating);
-
-class LayerTreeHostTimelinesTestNotifyAnimationFinished
-    : public LayerTreeHostTimelinesTest {
- public:
-  LayerTreeHostTimelinesTestNotifyAnimationFinished()
-      : called_animation_started_(false), called_animation_finished_(false) {}
-
-  void SetupTree() override {
-    LayerTreeHostTimelinesTest::SetupTree();
-    picture_ = FakePictureLayer::Create(layer_settings(), &client_);
-    picture_->SetBounds(gfx::Size(4, 4));
-    client_.set_bounds(picture_->bounds());
-    layer_tree_host()->root_layer()->AddChild(picture_);
-
-    AttachPlayersToTimeline();
-    player_->AttachLayer(picture_->id());
-    player_->set_layer_animation_delegate(this);
-  }
-
-  void BeginTest() override {
-    PostAddLongAnimationToMainThreadPlayer(player_.get());
-  }
-
-  void NotifyAnimationStarted(base::TimeTicks monotonic_time,
-                              TargetProperty::Type target_property,
-                              int group) override {
-    called_animation_started_ = true;
-    layer_tree_host()->AnimateLayers(base::TimeTicks::FromInternalValue(
-        std::numeric_limits<int64_t>::max()));
-    PostSetNeedsCommitToMainThread();
-  }
-
-  void NotifyAnimationFinished(base::TimeTicks monotonic_time,
-                               TargetProperty::Type target_property,
-                               int group) override {
-    called_animation_finished_ = true;
-    EndTest();
-  }
-
-  void AfterTest() override {
-    EXPECT_TRUE(called_animation_started_);
-    EXPECT_TRUE(called_animation_finished_);
-  }
-
- private:
-  bool called_animation_started_;
-  bool called_animation_finished_;
-  FakeContentLayerClient client_;
-  scoped_refptr<FakePictureLayer> picture_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
-    LayerTreeHostTimelinesTestNotifyAnimationFinished);
-
-}  // namespace
-}  // namespace cc
diff --git a/chrome/VERSION b/chrome/VERSION
index 2264ad0d..5b5baa1f 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=51
 MINOR=0
-BUILD=2673
+BUILD=2674
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
index b06f9e97..4f4015c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
@@ -26,7 +26,6 @@
 import org.chromium.base.ApplicationStatus.ApplicationStateListener;
 import org.chromium.base.BuildInfo;
 import org.chromium.base.CommandLineInitUtil;
-import org.chromium.base.PathUtils;
 import org.chromium.base.ResourceExtractor;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.TraceEvent;
@@ -120,7 +119,6 @@
     private static final long BOOT_TIMESTAMP_MARGIN_MS = 1000;
     private static final String PREF_LOCALE = "locale";
     private static final float FLOAT_EPSILON = 0.001f;
-    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "chrome";
     private static final String DEV_TOOLS_SERVER_SOCKET_PREFIX = "chrome";
     private static final String SESSIONS_UUID_PREF_KEY = "chromium.sync.sessions.id";
 
@@ -424,7 +422,6 @@
         if (!BuildInfo.hasLanguageApkSplits(this)) {
             ResourceExtractor.setResourcesToExtract(ResourceBundle.getActiveLocaleResources());
         }
-        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, this);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 3d354275..d2e4357c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -816,7 +816,7 @@
                         ChromeTabbedActivity.this, intent, false);
                 newIntent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
                 newIntent.putExtra(
-                        CustomTabIntentDataProvider.EXTRA_OPENED_BY_BROWSER, true);
+                        CustomTabIntentDataProvider.EXTRA_IS_OPENED_BY_CHROME, true);
                 ChromeLauncherActivity.addHerbIntentExtras(ChromeTabbedActivity.this,
                         newIntent, Uri.parse(IntentHandler.getUrlFromIntent(newIntent)));
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
index da23b434..82fde9f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -34,6 +34,8 @@
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.ChromeSwitches;
+import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.ChromeVersionInfo;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.IntentHandler.ExternalAppId;
@@ -56,6 +58,7 @@
 import org.chromium.chrome.browser.tabmodel.TabReparentingParams;
 import org.chromium.chrome.browser.toolbar.ToolbarControlContainer;
 import org.chromium.chrome.browser.util.ColorUtils;
+import org.chromium.chrome.browser.util.FeatureUtilities;
 import org.chromium.chrome.browser.util.IntentUtils;
 import org.chromium.chrome.browser.util.UrlUtilities;
 import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager;
@@ -189,7 +192,7 @@
         // alive.
         // TODO(dfalcantara): Once this is addressed on M50, consider transferring the Tab directly
         //                    via Tab reparenting.
-        if (mIntentDataProvider.isOpenedByBrowser()) {
+        if (mIntentDataProvider.isOpenedByChrome() && isHerbResultNeeded()) {
             createHerbResultIntent(RESULT_STOPPED);
             finish();
         }
@@ -273,7 +276,7 @@
                 new OnClickListener() {
                     @Override
                     public void onClick(View v) {
-                        if (mIntentDataProvider.isOpenedByBrowser()) {
+                        if (mIntentDataProvider.isOpenedByChrome() && isHerbResultNeeded()) {
                             createHerbResultIntent(RESULT_CLOSED);
                         }
                         RecordUserAction.record("CustomTabs.CloseButtonClicked");
@@ -499,7 +502,8 @@
     protected AppMenuPropertiesDelegate createAppMenuPropertiesDelegate() {
         return new CustomTabAppMenuPropertiesDelegate(this, mIntentDataProvider.getMenuTitles(),
                 mIntentDataProvider.shouldShowShareMenuItem(),
-                mIntentDataProvider.shouldShowBookmarkMenuItem());
+                mIntentDataProvider.shouldShowBookmarkMenuItem(),
+                mIntentDataProvider.isOpenedByChrome());
     }
 
     @Override
@@ -546,7 +550,7 @@
             if (getCurrentTabModel().getCount() > 1) {
                 getCurrentTabModel().closeTab(getActivityTab(), false, false, false);
             } else {
-                if (mIntentDataProvider.isOpenedByBrowser()) {
+                if (mIntentDataProvider.isOpenedByChrome() && isHerbResultNeeded()) {
                     createHerbResultIntent(RESULT_BACK_PRESSED);
                 }
                 finish();
@@ -569,7 +573,7 @@
                     public void onClick(View v) {
                         String creatorPackage =
                                 ApiCompatibilityUtils.getCreatorPackage(params.getPendingIntent());
-                        if (mIntentDataProvider.finishAfterOpeningInBrowser()
+                        if (mIntentDataProvider.isOpenedByChrome()
                                 && TextUtils.equals(getPackageName(), creatorPackage)) {
                             RecordUserAction.record(
                                     "TaskManagement.OpenInChromeActionButtonClicked");
@@ -755,40 +759,43 @@
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.putExtra(ChromeLauncherActivity.EXTRA_IS_ALLOWED_TO_RETURN_TO_PARENT, false);
 
-        boolean chromeIsDefault;
+        boolean willChromeHandleIntent = getIntentDataProvider().isOpenedByChrome();
         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
         StrictMode.allowThreadDiskWrites();
         try {
-            chromeIsDefault = ExternalNavigationDelegateImpl
+            willChromeHandleIntent |= ExternalNavigationDelegateImpl
                     .willChromeHandleIntent(this, intent, true);
         } finally {
             StrictMode.setThreadPolicy(oldPolicy);
         }
 
-        boolean enableTabReparenting = ChromeVersionInfo.isLocalBuild()
-                || ChromeVersionInfo.isCanaryBuild() || ChromeVersionInfo.isDevBuild()
-                || FieldTrialList.findFullName("TabReparenting").startsWith("Enabled");
-        if (enableTabReparenting && chromeIsDefault) {
-            // Take the activity tab and set it aside for reparenting.
-            final Tab tab = getActivityTab();
-            // TODO(yusufo): The removal should happen as a part of the callback or as a part of
-            // onDestroy when finish() gets called. Find a way to do this properly without confusing
-            // the TabModel and without hiding the tab. crbug.com/590278
-            getCurrentTabModel().removeTab(getActivityTab());
-            mMainTab = null;
-            tab.getContentViewCore().updateWindowAndroid(null);
-            tab.attachTabContentManager(null);
-
-            Runnable finalizeCallback = new Runnable() {
-                @Override
-                public void run() {
-                    finish();
-                }
-            };
-            AsyncTabParamsManager.add(
-                    tab.getId(), new TabReparentingParams(tab, intent, finalizeCallback));
-            intent.putExtra(IntentHandler.EXTRA_TAB_ID, tab.getId());
+        if (willChromeHandleIntent) {
             intent.setPackage(getPackageName());
+
+            boolean enableTabReparenting = ChromeVersionInfo.isLocalBuild()
+                    || ChromeVersionInfo.isCanaryBuild() || ChromeVersionInfo.isDevBuild()
+                    || FieldTrialList.findFullName("TabReparenting").startsWith("Enabled");
+            if (enableTabReparenting) {
+                // Take the activity tab and set it aside for reparenting.
+                final Tab tab = getActivityTab();
+                // TODO(yusufo): The removal should happen as a part of the callback or as a part of
+                // onDestroy when finish() gets called. Find a way to do this properly without
+                // confusing the TabModel and without hiding the tab. crbug.com/590278
+                getCurrentTabModel().removeTab(getActivityTab());
+                mMainTab = null;
+                tab.getContentViewCore().updateWindowAndroid(null);
+                tab.attachTabContentManager(null);
+
+                Runnable finalizeCallback = new Runnable() {
+                    @Override
+                    public void run() {
+                        finish();
+                    }
+                };
+                AsyncTabParamsManager.add(
+                        tab.getId(), new TabReparentingParams(tab, intent, finalizeCallback));
+                intent.putExtra(IntentHandler.EXTRA_TAB_ID, tab.getId());
+            }
         }
 
         // Temporarily allowing disk access while fixing. TODO: http://crbug.com/581860
@@ -804,6 +811,19 @@
     }
 
     /**
+     * @return Whether {@link ChromeTabbedActivity} is waiting for a result from this Activity.
+     */
+    private boolean isHerbResultNeeded() {
+        if (!TextUtils.equals(FeatureUtilities.getHerbFlavor(), ChromeSwitches.HERB_FLAVOR_DILL)) {
+            return false;
+        }
+
+        String callingActivity =
+                getCallingActivity() == null ? null : getCallingActivity().getClassName();
+        return TextUtils.equals(callingActivity, ChromeTabbedActivity.class.getName());
+    }
+
+    /**
      * Lets the original Activity know how this {@link CustomTabActivity} was finished.
      */
     private void createHerbResultIntent(int result) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
index f4ff270..4ca7cb01 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
@@ -12,6 +12,7 @@
 import android.view.Menu;
 import android.view.MenuItem;
 
+import org.chromium.base.BuildInfo;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeActivity;
@@ -41,7 +42,8 @@
      * Creates an {@link CustomTabAppMenuPropertiesDelegate} instance.
      */
     public CustomTabAppMenuPropertiesDelegate(final ChromeActivity activity,
-            List<String> menuEntries, boolean showShare, boolean showBookmark) {
+            List<String> menuEntries, boolean showShare, boolean showBookmark,
+            final boolean isOpenedByChrome) {
         super(activity);
         mMenuEntries = menuEntries;
         mShowShare = showShare;
@@ -49,13 +51,23 @@
         mDefaultBrowserFetcher = new AsyncTask<Void, Void, String>() {
             @Override
             protected String doInBackground(Void... params) {
-                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SAMPLE_URL));
-                PackageManager pm = activity.getPackageManager();
-                ResolveInfo info = pm.resolveActivity(intent, 0);
-                return info != null && info.match != 0
-                        ? activity.getString(
-                                R.string.menu_open_in_product, info.loadLabel(pm).toString())
-                        : activity.getString(R.string.menu_open_in_product_default);
+                String packageLabel = null;
+                if (isOpenedByChrome) {
+                    // If the Custom Tab was created by Chrome, Chrome should open it.
+                    packageLabel = BuildInfo.getPackageLabel(activity);
+                } else {
+                    // Check if there is a default handler for the Intent.  If so, grab its label.
+                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SAMPLE_URL));
+                    PackageManager pm = activity.getPackageManager();
+                    ResolveInfo info = pm.resolveActivity(intent, 0);
+                    if (info != null && info.match != 0) {
+                        packageLabel = info.loadLabel(pm).toString();
+                    }
+                }
+
+                return packageLabel == null
+                        ? activity.getString(R.string.menu_open_in_product_default)
+                        : activity.getString(R.string.menu_open_in_product, packageLabel);
             }
         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
index 3b360c7..15787616 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -49,19 +49,11 @@
     public static final String EXTRA_KEEP_ALIVE = "android.support.customtabs.extra.KEEP_ALIVE";
 
     /**
-     * Herb: Extra used by Chrome to tell the CustomTabActivity to finish itself and open the
-     * current URL in the browser.  Guarded explicitly for use only by PendingIntents with the
-     * Chrome package.
+     * Herb: Extra that indicates whether or not the Custom Tab is being launched by an Intent fired
+     * by Chrome itself.
      */
-    public static final String EXTRA_FINISH_AFTER_OPENING_IN_BROWSER =
-            "org.chromium.chrome.browser.customtabs.FINISH_AFTER_OPENING_IN_BROWSER";
-
-    /**
-     * Herb: Extra used by the main Chrome browser to tell the {@link CustomTabActivity} that it
-     * sits on top of the main browser Activity.
-     */
-    public static final String EXTRA_OPENED_BY_BROWSER =
-            "org.chromium.chrome.browser.customtabs.OPENED_BY_BROWSER";
+    public static final String EXTRA_IS_OPENED_BY_CHROME =
+            "org.chromium.chrome.browser.customtabs.IS_OPENED_BY_CHROME";
 
     /**
      * Herb: Extra used by the main Chrome browser to enable the bookmark icon in the menu.
@@ -94,11 +86,8 @@
     // OnFinished listener for PendingIntents. Used for testing only.
     private PendingIntent.OnFinished mOnFinished;
 
-    /** Herb: "Open in Browser" will send the Tab to the Browser and kill this Activity. */
-    private boolean mFinishAfterOpeningInBrowser;
-
-    /** Herb: Whether or not this CustomTabActivity was opened by the Browser directly. */
-    private boolean mIsOpenedByBrowser;
+    /** Herb: Whether this CustomTabActivity was explicitly started by another Chrome Activity. */
+    private boolean mIsOpenedByChrome;
 
     /** Herb: Whether or not the bookmark button should be shown. */
     private boolean mShowBookmarkItem;
@@ -415,17 +404,10 @@
     }
 
     /**
-     * @return See {@link #EXTRA_FINISH_AFTER_OPENING_IN_BROWSER}.
+     * @return See {@link #EXTRA_IS_OPENED_BY_CHROME}.
      */
-    boolean finishAfterOpeningInBrowser() {
-        return mFinishAfterOpeningInBrowser;
-    }
-
-    /**
-     * @return See {@link #EXTRA_OPENED_BY_BROWSER}.
-     */
-    boolean isOpenedByBrowser() {
-        return mIsOpenedByBrowser;
+    boolean isOpenedByChrome() {
+        return mIsOpenedByChrome;
     }
 
     /**
@@ -442,10 +424,8 @@
         }
         if (!IntentHandler.isIntentChromeOrFirstParty(intent, context)) return;
 
-        mFinishAfterOpeningInBrowser = IntentUtils.safeGetBooleanExtra(
-                intent, EXTRA_FINISH_AFTER_OPENING_IN_BROWSER, false);
-        mIsOpenedByBrowser = IntentUtils.safeGetBooleanExtra(
-                intent, EXTRA_OPENED_BY_BROWSER, false);
+        mIsOpenedByChrome = IntentUtils.safeGetBooleanExtra(
+                intent, EXTRA_IS_OPENED_BY_CHROME, false);
         mShowBookmarkItem = IntentUtils.safeGetBooleanExtra(
                 intent, EXTRA_SHOW_STAR_ICON, false);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
index f23bfb5..c314adf 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
@@ -30,6 +30,7 @@
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.ApplicationStatus;
+import org.chromium.base.BuildInfo;
 import org.chromium.base.CommandLineInitUtil;
 import org.chromium.base.Log;
 import org.chromium.base.TraceEvent;
@@ -64,12 +65,14 @@
 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelSelector;
 import org.chromium.chrome.browser.util.FeatureUtilities;
 import org.chromium.chrome.browser.util.IntentUtils;
+import org.chromium.chrome.browser.util.UrlUtilities;
 import org.chromium.chrome.browser.webapps.WebappLauncherActivity;
 import org.chromium.content.browser.crypto.CipherFactory;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.ui.base.PageTransition;
 
 import java.lang.ref.WeakReference;
+import java.net.URI;
 import java.util.List;
 
 /**
@@ -296,9 +299,11 @@
      * @return Whether or not an Herb prototype may hijack an Intent.
      */
     public static boolean canBeHijackedByHerb(Intent intent) {
+        String url = IntentHandler.getUrlFromIntent(intent);
+
         // Only VIEW Intents with URLs are rerouted to Custom Tabs.
         if (intent == null || !TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())
-                || TextUtils.isEmpty(IntentHandler.getUrlFromIntent(intent))) {
+                || TextUtils.isEmpty(url)) {
             return false;
         }
 
@@ -309,6 +314,14 @@
             return false;
         }
 
+        // Don't reroute internal chrome URLs.
+        try {
+            URI uri = URI.create(url);
+            if (UrlUtilities.isInternalScheme(uri)) return false;
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+
         // Custom Tabs have to be available.
         if (!ChromePreferenceManager.getInstance(context).getCustomTabsEnabled()) return false;
 
@@ -364,12 +377,13 @@
                 PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
         herbBundle.putParcelable(CustomTabsIntent.KEY_PENDING_INTENT, pendingIntent);
 
-        herbBundle.putString(CustomTabsIntent.KEY_DESCRIPTION,
-                context.getResources().getString(R.string.menu_open_in_chrome));
+        String openString = context.getString(
+                R.string.menu_open_in_product, BuildInfo.getPackageLabel(context));
+        herbBundle.putString(CustomTabsIntent.KEY_DESCRIPTION, openString);
 
         newIntent.putExtra(CustomTabsIntent.EXTRA_ACTION_BUTTON_BUNDLE, herbBundle);
         newIntent.putExtra(CustomTabsIntent.EXTRA_DEFAULT_SHARE_MENU_ITEM, true);
-        newIntent.putExtra(CustomTabIntentDataProvider.EXTRA_FINISH_AFTER_OPENING_IN_BROWSER, true);
+        newIntent.putExtra(CustomTabIntentDataProvider.EXTRA_IS_OPENED_BY_CHROME, true);
         newIntent.putExtra(CustomTabIntentDataProvider.EXTRA_SHOW_STAR_ICON, true);
 
         // Mark this as a trusted Chrome Intent.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java
index 7c6e1ac29..41ea156a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java
@@ -18,6 +18,7 @@
 import android.view.WindowManager;
 
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.preferences.website.ContentSetting;
 import org.chromium.chrome.browser.preferences.website.FullscreenInfo;
 import org.chromium.chrome.browser.tab.Tab;
@@ -309,7 +310,9 @@
         mTabInFullscreen = tab;
         FullscreenInfo fullscreenInfo = new FullscreenInfo(tab.getUrl(), null, tab.isIncognito());
         ContentSetting fullscreenPermission = fullscreenInfo.getContentSetting();
-        if (fullscreenPermission != ContentSetting.ALLOW) {
+        // In simplified fullscreen mode, do not show the infobar (always allow). The toast will
+        // still be shown.
+        if (fullscreenPermission != ContentSetting.ALLOW && !isSimplifiedFullscreenUIEnabled()) {
             mFullscreenInfoBarDelegate = FullscreenInfoBarDelegate.create(this, tab);
         }
     }
@@ -379,4 +382,8 @@
         }
         return flags;
     }
+
+    private static boolean isSimplifiedFullscreenUIEnabled() {
+        return ChromeFeatureList.isEnabled("ViewsSimplifiedFullscreenUI");
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
index 91f0dee..e52423b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -22,6 +22,7 @@
 import org.chromium.base.CommandLine;
 import org.chromium.base.ContentUriUtils;
 import org.chromium.base.Log;
+import org.chromium.base.PathUtils;
 import org.chromium.base.ResourceExtractor;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.TraceEvent;
@@ -58,6 +59,7 @@
  */
 public class ChromeBrowserInitializer {
     private static final String TAG = "BrowserInitializer";
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "chrome";
     private static ChromeBrowserInitializer sChromeBrowserInitiliazer;
 
     private final Handler mHandler;
@@ -129,6 +131,8 @@
     public void handlePreNativeStartup(final BrowserParts parts) {
         assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread";
 
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, mApplication);
+
         preInflationStartup();
         parts.preInflationStartup();
         preInflationStartupDone();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java
index 9ca2bab..2104cf3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java
@@ -10,6 +10,7 @@
 import com.google.android.gms.gcm.GcmListenerService;
 import com.google.ipc.invalidation.ticl.android2.channel.AndroidGcmController;
 
+import org.chromium.base.PathUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.components.gcm_driver.GCMDriver;
 
@@ -18,6 +19,7 @@
  */
 public class ChromeGcmListenerService extends GcmListenerService {
     private static final String TAG = "ChromeGcmListener";
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "chrome";
 
     @Override
     public void onMessageReceived(String from, Bundle data) {
@@ -58,6 +60,8 @@
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
+                PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX,
+                        getApplicationContext());
                 GCMDriver.onMessageReceived(getApplicationContext(), appId, data);
             }
         });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
index e5587f3..405063d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -16,6 +16,7 @@
 import android.view.MotionEvent.PointerProperties;
 import android.widget.FrameLayout;
 
+import org.chromium.base.PathUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.base.library_loader.ProcessInitException;
@@ -45,6 +46,8 @@
         implements MockTabModelDelegate {
     private static final String TAG = "LayoutManagerTest";
 
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "content";
+
     private long mLastDownTime = 0;
 
     private TabModelSelector mTabModelSelector;
@@ -465,6 +468,9 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX,
+                getInstrumentation().getTargetContext());
+
         // Load the browser process.
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
index 3cd7597..c50b6de8 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -37,6 +37,7 @@
 import android.widget.EditText;
 import android.widget.ImageButton;
 
+import org.chromium.base.PathUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.library_loader.LibraryProcessType;
@@ -104,6 +105,7 @@
     private static final String TEST_PAGE_2 = "/chrome/test/data/android/test.html";
     private static final String FRAGMENT_TEST_PAGE = "/chrome/test/data/android/fragment.html";
     private static final String TEST_MENU_TITLE = "testMenuTitle";
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "chrome";
 
     private static int sIdToIncrement = 1;
 
@@ -119,6 +121,8 @@
                 getInstrumentation().getContext(), Environment.getExternalStorageDirectory());
         mTestPage = mTestServer.getURL(TEST_PAGE);
         mTestPage2 = mTestServer.getURL(TEST_PAGE_2);
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX,
+                getInstrumentation().getTargetContext().getApplicationContext());
         LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER)
                 .ensureInitialized(getInstrumentation().getTargetContext().getApplicationContext());
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java
index 7655cb02..b7c9ae1 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java
@@ -19,6 +19,7 @@
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import org.chromium.base.PathUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.library_loader.LibraryProcessType;
@@ -34,6 +35,7 @@
     private static final String URL = "http://www.google.com";
     private static final String URL2 = "https://www.android.com";
     private static final String INVALID_SCHEME_URL = "intent://www.google.com";
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "chrome";
 
     private Context mContext;
 
@@ -41,6 +43,8 @@
     protected void setUp() throws Exception {
         super.setUp();
         mContext = getInstrumentation().getTargetContext().getApplicationContext();
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX,
+                mContext);
         LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER)
                 .ensureInitialized(mContext);
         mCustomTabsConnection = CustomTabsTestUtils.setUpConnection((Application) mContext);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/DocumentActivityHWATest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/DocumentActivityHWATest.java
index e800971b..5d490b8 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/DocumentActivityHWATest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/DocumentActivityHWATest.java
@@ -11,27 +11,39 @@
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.document.DocumentActivity;
-import org.chromium.chrome.browser.document.DocumentModeTest;
+import org.chromium.chrome.browser.document.DocumentModeTestBase;
 
 /**
  * Tests that DocumentActivity is hardware accelerated only high-end devices.
  */
-public class DocumentActivityHWATest extends DocumentModeTest {
+public class DocumentActivityHWATest extends DocumentModeTestBase {
 
     @SmallTest
     public void testHardwareAcceleration() throws Exception {
-        Utils.assertHardwareAcceleration(startAndWaitActivity());
+        Utils.assertHardwareAcceleration(startAndWaitActivity(false));
+    }
+
+    @SmallTest
+    public void testHardwareAccelerationIncognito() throws Exception {
+        Utils.assertHardwareAcceleration(startAndWaitActivity(true));
     }
 
     @Restriction(RESTRICTION_TYPE_LOW_END_DEVICE)
     @SmallTest
     public void testNoRenderThread() throws Exception {
-        startAndWaitActivity();
+        startAndWaitActivity(false);
         Utils.assertNoRenderThread();
     }
 
-    private DocumentActivity startAndWaitActivity() throws Exception {
-        launchViaViewIntent(false, URL_1, "Page 1");
+    @Restriction(RESTRICTION_TYPE_LOW_END_DEVICE)
+    @SmallTest
+    public void testNoRenderThreadIncognito() throws Exception {
+        startAndWaitActivity(true);
+        Utils.assertNoRenderThread();
+    }
+
+    private DocumentActivity startAndWaitActivity(boolean incognito) throws Exception {
+        launchViaViewIntent(incognito, URL_1, "Page 1");
         return (DocumentActivity) ApplicationStatus.getLastTrackedFocusedActivity();
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/IncognitoDocumentActivityHWATest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/IncognitoDocumentActivityHWATest.java
deleted file mode 100644
index ffdbab5..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/IncognitoDocumentActivityHWATest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.hardware_acceleration;
-
-import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_LOW_END_DEVICE;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-import org.chromium.base.ApplicationStatus;
-import org.chromium.base.test.util.Restriction;
-import org.chromium.chrome.browser.document.DocumentModeTest;
-import org.chromium.chrome.browser.document.IncognitoDocumentActivity;
-
-/**
- * Tests that IncognitoDocumentActivity is hardware accelerated only high-end devices.
- */
-public class IncognitoDocumentActivityHWATest extends DocumentModeTest {
-
-    @SmallTest
-    public void testHardwareAcceleration() throws Exception {
-        Utils.assertHardwareAcceleration(startAndWaitActivity());
-    }
-
-    @Restriction(RESTRICTION_TYPE_LOW_END_DEVICE)
-    @SmallTest
-    public void testNoRenderThread() throws Exception {
-        startAndWaitActivity();
-        Utils.assertNoRenderThread();
-    }
-
-    private IncognitoDocumentActivity startAndWaitActivity() throws Exception {
-        launchViaViewIntent(true, URL_1, "Page 1");
-        return (IncognitoDocumentActivity) ApplicationStatus.getLastTrackedFocusedActivity();
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
index aa30a90..c0f9be32 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java
@@ -13,6 +13,7 @@
 import android.test.UiThreadTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import org.chromium.base.PathUtils;
 import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.base.library_loader.ProcessInitException;
 import org.chromium.base.test.util.DisableIf;
@@ -29,11 +30,16 @@
     private static final String SEARCH_URL_1 = "https://www.google.com/search?q=potatoes";
     private static final String SEARCH_URL_2 = "https://www.google.co.jp/webhp?#q=dinosaurs";
 
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "content";
+
     @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/575277")
     @SmallTest
     @Feature({"Location"})
     @UiThreadTest
     public void testGeolocationHeader() throws ProcessInitException {
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX,
+                getInstrumentation().getTargetContext());
+
         Context targetContext = getInstrumentation().getTargetContext();
         BrowserStartupController.get(targetContext, LibraryProcessType.PROCESS_BROWSER)
                 .startBrowserProcessesSync(false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/push_messaging/PushMessagingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/push_messaging/PushMessagingTest.java
index bb9ea3c1..fd50d18c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/push_messaging/PushMessagingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/push_messaging/PushMessagingTest.java
@@ -14,6 +14,7 @@
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
 
+import org.chromium.base.PathUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.notifications.NotificationTestBase;
@@ -40,6 +41,7 @@
     private static final String ABOUT_BLANK = "about:blank";
     private static final String SENDER_ID_BUNDLE_KEY = "from";
     private static final int TITLE_UPDATE_TIMEOUT_SECONDS = (int) scaleTimeout(5);
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "chrome";
 
     private final CallbackHelper mMessageHandledHelper;
     private String mPushTestPage;
@@ -173,6 +175,7 @@
                 Context context = getInstrumentation().getTargetContext().getApplicationContext();
                 Bundle extras = new Bundle();
                 extras.putString(SENDER_ID_BUNDLE_KEY, senderId);
+                PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, context);
                 GCMDriver.onMessageReceived(context, appId, extras);
             }
         });
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 3922c6d..e737b9a 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -5664,7 +5664,7 @@
 
   <!-- Platform verification UI -->
   <message name="IDS_PLATFORM_VERIFICATION_DIALOG_HEADLINE" desc="The label to describe what the dialog wants to confirm.">
-    <ph name="DOMAIN">$1<ex>example.com</ex></ph> requires your device's identity to be verified, by Google, to determine eligibility for enhanced playback of protected media. <ph name="LEARN_MORE">$2<ex>Learn more</ex></ph>.
+    <ph name="DOMAIN">$1<ex>example.com</ex></ph> wants your device's identity to be verified, by Google, to determine eligibility for enhanced playback of protected media. <ph name="LEARN_MORE">$2<ex>Learn more</ex></ph>.
   </message>
   <message name="IDS_PLATFORM_VERIFICATION_DIALOG_ALLOW" desc="The button label to allow access of HD playback.">
     OK, I got it
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index ceec21c..9541d09 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -12163,7 +12163,7 @@
           Know your unique device identifier
         </message>
         <message name="IDS_PROTECTED_MEDIA_IDENTIFIER_INFOBAR_QUESTION" desc="Question asked on the infobar whenever URL wants to access protected media identifier. It shows the origin of the URL.">
-          <ph name="URL">$1<ex>https://www.youtube.com</ex></ph> needs to uniquely identify your device to play premium content.
+          <ph name="URL">$1<ex>https://www.youtube.com</ex></ph> wants to uniquely identify your device to play premium content.
         </message>
       </if>
 
diff --git a/chrome/app/mash/BUILD.gn b/chrome/app/mash/BUILD.gn
index 7f2aeb0..deced6b 100644
--- a/chrome/app/mash/BUILD.gn
+++ b/chrome/app/mash/BUILD.gn
@@ -10,8 +10,6 @@
     "mash_runner.h",
   ]
   deps = [
-    ":chrome_manifest",
-    ":manifest",
     "//ash/mus:lib",
     "//ash/resources",
     "//base:i18n",
@@ -30,6 +28,10 @@
     "//mojo/shell/runner/host:lib",
     "//url",
   ]
+  data_deps = [
+    ":chrome_manifest",
+    ":manifest",
+  ]
 
   if (is_linux && !is_android) {
     deps += [ "//components/font_service:lib" ]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 706d58e96..13b958c5 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -109,10 +109,6 @@
 #include "ui/ozone/public/ozone_switches.h"
 #endif
 
-#if defined(TOOLKIT_VIEWS)
-#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
-#endif
-
 using flags_ui::FeatureEntry;
 using flags_ui::kOsMac;
 using flags_ui::kOsWin;
@@ -1607,11 +1603,9 @@
      IDS_FLAGS_NEW_TASK_MANAGER_DESCRIPTION, kOsDesktop,
      SINGLE_DISABLE_VALUE_TYPE(switches::kDisableNewTaskManager)},
 #endif  // defined(ENABLE_TASK_MANAGER)
-#if defined(TOOLKIT_VIEWS)
     {"simplified-fullscreen-ui", IDS_FLAGS_SIMPLIFIED_FULLSCREEN_UI_NAME,
-     IDS_FLAGS_SIMPLIFIED_FULLSCREEN_UI_DESCRIPTION, kOsDesktop,
-     FEATURE_VALUE_TYPE(ExclusiveAccessManager::kSimplifiedUIFeature)},
-#endif  // defined(TOOLKIT_VIEWS)
+     IDS_FLAGS_SIMPLIFIED_FULLSCREEN_UI_DESCRIPTION, kOsAll,
+     FEATURE_VALUE_TYPE(features::kSimplifiedFullscreenUI)},
 #if defined(OS_ANDROID)
     {"progress-bar-animation", IDS_FLAGS_PROGRESS_BAR_ANIMATION_NAME,
      IDS_FLAGS_PROGRESS_BAR_ANIMATION_DESCRIPTION, kOsAndroid,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index d455055..a7491e7 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -11,6 +11,7 @@
 #include "base/android/jni_string.h"
 #include "base/feature_list.h"
 #include "base/macros.h"
+#include "chrome/common/chrome_features.h"
 #include "jni/ChromeFeatureList_jni.h"
 
 using base::android::ConvertJavaStringToUTF8;
@@ -27,6 +28,7 @@
     &kNTPOfflinePagesFeature,
     &kNTPSnippetsFeature,
     &kPhysicalWebFeature,
+    &features::kSimplifiedFullscreenUI,
 };
 
 }  // namespace
diff --git a/chrome/browser/apps/app_browsertest.cc b/chrome/browser/apps/app_browsertest.cc
index 0a044d75..66d84ef 100644
--- a/chrome/browser/apps/app_browsertest.cc
+++ b/chrome/browser/apps/app_browsertest.cc
@@ -447,13 +447,20 @@
                        DisallowBackgroundPageNavigation) {
   // The test will try to open in app urls and external urls via clicking links
   // and window.open(). Only the external urls should succeed in opening tabs.
-  TabsAddedNotificationObserver observer(2);
+  // TODO(lazyboy): non-external urls also succeed right now because of
+  // http://crbug.com/585570 not being fixed. Fix the test once the bug is
+  // fixed.
+  // const size_t kExpectedNumberOfTabs = 2u;
+  const size_t kExpectedNumberOfTabs = 6u;
+  TabsAddedNotificationObserver observer(kExpectedNumberOfTabs);
   ASSERT_TRUE(RunPlatformAppTest("platform_apps/background_page_navigation")) <<
       message_;
   observer.Wait();
-  ASSERT_EQ(2U, observer.tabs().size());
-  EXPECT_EQ(GURL(kChromiumURL), observer.tabs()[0]->GetURL());
-  EXPECT_EQ(GURL(kChromiumURL), observer.tabs()[1]->GetURL());
+  ASSERT_EQ(kExpectedNumberOfTabs, observer.tabs().size());
+  EXPECT_EQ(GURL(kChromiumURL),
+            observer.tabs()[kExpectedNumberOfTabs - 1]->GetURL());
+  EXPECT_EQ(GURL(kChromiumURL),
+            observer.tabs()[kExpectedNumberOfTabs - 2]->GetURL());
 }
 
 // Failing on some Win and Linux buildbots.  See crbug.com/354425.
diff --git a/chrome/browser/bookmarks/bookmark_stats.h b/chrome/browser/bookmarks/bookmark_stats.h
index bcfea72..3b1b47fc 100644
--- a/chrome/browser/bookmarks/bookmark_stats.h
+++ b/chrome/browser/bookmarks/bookmark_stats.h
@@ -31,8 +31,8 @@
   BOOKMARK_LAUNCH_LOCATION_BAR_SUBFOLDER,
   BOOKMARK_LAUNCH_LOCATION_CONTEXT_MENU,
 
-  // Bookmarks menu within wrench menu.
-  BOOKMARK_LAUNCH_LOCATION_WRENCH_MENU,
+  // Bookmarks menu within app menu.
+  BOOKMARK_LAUNCH_LOCATION_APP_MENU,
   // Bookmark manager.
   BOOKMARK_LAUNCH_LOCATION_MANAGER,
   // Autocomplete suggestion.
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 5a3ec57..c52adce 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -16,6 +16,7 @@
 #include "base/files/scoped_file.h"
 #include "base/lazy_instance.h"
 #include "base/macros.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
@@ -380,6 +381,12 @@
 };
 #endif
 
+enum AppLoadedInTabSource {
+  APP_LOADED_IN_TAB_SOURCE_APP = 0,
+  APP_LOADED_IN_TAB_SOURCE_BACKGROUND_PAGE,
+  APP_LOADED_IN_TAB_SOURCE_MAX
+};
+
 // Returns a copy of the given url with its host set to given host and path set
 // to given path. Other parts of the url will be the same.
 GURL ReplaceURLHostAndPath(const GURL& url,
@@ -2232,11 +2239,20 @@
     InfoMap* map = io_data->GetExtensionInfoMap();
     const Extension* extension =
         map->extensions().GetExtensionOrAppByURL(opener_url);
-    // Platform apps and their background pages should not be able to call
-    // window.open() to load v2 apps in regular tab.
-    // Simply disallow window.open() calls in this case.
-    if (extension && extension->is_platform_app())
-      return false;
+    // TODO(lazyboy): http://crbug.com/585570, if |extension| is a platform app,
+    // disallow loading it in a tab via window.open(). Currently there are apps
+    // that rely on this to be allowed to get Cast API to work, so we are
+    // allowing this temporarily. Once Media Router is available on stable, this
+    // exception should not be required.
+    if (extension && extension->is_platform_app()) {
+      AppLoadedInTabSource source =
+          opener_top_level_frame_url ==
+                  extensions::BackgroundInfo::GetBackgroundURL(extension)
+              ? APP_LOADED_IN_TAB_SOURCE_BACKGROUND_PAGE
+              : APP_LOADED_IN_TAB_SOURCE_APP;
+      UMA_HISTOGRAM_ENUMERATION("Extensions.AppLoadedInTab", source,
+                                APP_LOADED_IN_TAB_SOURCE_MAX);
+    }
   }
 #endif
 
diff --git a/chrome/browser/extensions/api/automation/automation_apitest.cc b/chrome/browser/extensions/api/automation/automation_apitest.cc
index 7bed325..7eed2f3e 100644
--- a/chrome/browser/extensions/api/automation/automation_apitest.cc
+++ b/chrome/browser/extensions/api/automation/automation_apitest.cc
@@ -172,6 +172,13 @@
       << message_;
 }
 
+IN_PROC_BROWSER_TEST_F(AutomationApiTest, DesktopFocusIframe) {
+  StartEmbeddedTestServer();
+  ASSERT_TRUE(
+      RunExtensionSubtest("automation/tests/desktop", "focus_iframe.html"))
+      << message_;
+}
+
 IN_PROC_BROWSER_TEST_F(AutomationApiTest, DesktopFocusViews) {
   AutomationManagerAura::GetInstance()->Enable(browser()->profile());
   // Trigger the shelf subtree to be computed.
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
index 95fbfd1f..79e6051c 100644
--- a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
+++ b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
@@ -632,6 +632,14 @@
   // Test that hsl() values 'hsl(120, 100%, 50%)' set color correctly.
   ASSERT_EQ(SkColorSetARGB(255, 0, 255, 0),
             action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId));
+
+  // Test basic color keyword set correctly.
+  ui_test_utils::NavigateToURL(browser(),
+                               GURL(extension->GetResourceURL("update4.html")));
+  ASSERT_TRUE(catcher.GetNextResult());
+
+  ASSERT_EQ(SkColorSetARGB(255, 0, 0, 255),
+            action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, Getters) {
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
index b749865..4a6ca8d 100644
--- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc
+++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -56,6 +56,8 @@
 const char kOpenPopupError[] =
     "Failed to show popup either because there is an existing popup or another "
     "error occurred.";
+const char kInvalidColorError[] =
+    "The color specification could not be parsed.";
 
 }  // namespace
 
@@ -580,8 +582,10 @@
   } else if (color_value->IsType(base::Value::TYPE_STRING)) {
     std::string color_string;
     EXTENSION_FUNCTION_VALIDATE(details_->GetString("color", &color_string));
-    if (!image_util::ParseCssColorString(color_string, &color))
+    if (!image_util::ParseCssColorString(color_string, &color)) {
+      error_ = kInvalidColorError;
       return false;
+    }
   }
 
   extension_action_->SetBadgeBackgroundColor(tab_id_, color);
diff --git a/chrome/browser/media/router/media_router_metrics.cc b/chrome/browser/media/router/media_router_metrics.cc
index 0403fe0..cda93c8e 100644
--- a/chrome/browser/media/router/media_router_metrics.cc
+++ b/chrome/browser/media/router/media_router_metrics.cc
@@ -53,4 +53,15 @@
       static_cast<int>(MediaRouterUserAction::TOTAL_COUNT));
 }
 
+// static
+void MediaRouterMetrics::RecordRouteCreationOutcome(
+    MediaRouterRouteCreationOutcome outcome) {
+  DCHECK_NE(static_cast<int>(outcome),
+            static_cast<int>(
+                MediaRouterRouteCreationOutcome::TOTAL_COUNT));
+  UMA_HISTOGRAM_ENUMERATION(
+    "MediaRouter.Route.CreationOutcome", static_cast<int>(outcome),
+    static_cast<int>(MediaRouterRouteCreationOutcome::TOTAL_COUNT));
+}
+
 }  // namespace media_router
diff --git a/chrome/browser/media/router/media_router_metrics.h b/chrome/browser/media/router/media_router_metrics.h
index 2f01c431c..dbdeb198 100644
--- a/chrome/browser/media/router/media_router_metrics.h
+++ b/chrome/browser/media/router/media_router_metrics.h
@@ -46,6 +46,16 @@
   TOTAL_COUNT = 15
 };
 
+// The possible outcomes from a route creation response.
+enum class MediaRouterRouteCreationOutcome {
+  SUCCESS = 0,
+  FAILURE_NO_ROUTE = 1,
+  FAILURE_INVALID_SINK = 2,
+
+  // Note: Add entries only immediately above this line.
+  TOTAL_COUNT = 3,
+};
+
 // The possible actions a user can take while interacting with the Media Router
 // dialog.
 enum class MediaRouterUserAction {
@@ -83,6 +93,10 @@
   // opened.
   static void RecordMediaRouterInitialUserAction(
       MediaRouterUserAction action);
+
+  // Records the outcome in a create route response.
+  static void RecordRouteCreationOutcome(
+      MediaRouterRouteCreationOutcome outcome);
 };
 
 }  // namespace media_router
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 9f0ac42..f84fa54 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -247,12 +247,8 @@
       return true;
     }
 #endif
-    std::string uma_histogram_suffix(
-        password_manager::metrics_util::GroupIdToString(
-            password_manager::metrics_util::MonitoredDomainGroupId(
-                form_to_save->pending_credentials().signon_realm, GetPrefs())));
-    SavePasswordInfoBarDelegate::Create(web_contents(), std::move(form_to_save),
-                                        uma_histogram_suffix);
+    SavePasswordInfoBarDelegate::Create(web_contents(),
+                                        std::move(form_to_save));
 #else
     NOTREACHED() << "Aura platforms should always use the bubble";
 #endif
@@ -311,14 +307,14 @@
 }
 
 void ChromePasswordManagerClient::NotifyUserAutoSignin(
-    ScopedVector<autofill::PasswordForm> local_forms) {
+    ScopedVector<autofill::PasswordForm> local_forms,
+    const GURL& origin) {
   DCHECK(!local_forms.empty());
 #if BUILDFLAG(ANDROID_JAVA_UI)
   ShowAutoSigninPrompt(web_contents(), local_forms[0]->username_value);
 #else
   PasswordsClientUIDelegateFromWebContents(web_contents())
-      ->OnAutoSignin(std::move(local_forms));
-
+      ->OnAutoSignin(std::move(local_forms), origin);
 #endif
 }
 
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index e645f69..8d0f023 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -63,7 +63,8 @@
   void ForceSavePassword() override;
   void GeneratePassword() override;
   void NotifyUserAutoSignin(
-      ScopedVector<autofill::PasswordForm> local_forms) override;
+      ScopedVector<autofill::PasswordForm> local_forms,
+      const GURL& origin) override;
   void NotifyUserCouldBeAutoSignedIn(
       scoped_ptr<autofill::PasswordForm> form) override;
   void NotifySuccessfulLoginWithExistingPassword(
diff --git a/chrome/browser/password_manager/save_password_infobar_delegate.cc b/chrome/browser/password_manager/save_password_infobar_delegate.cc
index 8372e14..2b65cfc 100644
--- a/chrome/browser/password_manager/save_password_infobar_delegate.cc
+++ b/chrome/browser/password_manager/save_password_infobar_delegate.cc
@@ -25,8 +25,7 @@
 // static
 void SavePasswordInfoBarDelegate::Create(
     content::WebContents* web_contents,
-    scoped_ptr<password_manager::PasswordFormManager> form_to_save,
-    const std::string& uma_histogram_suffix) {
+    scoped_ptr<password_manager::PasswordFormManager> form_to_save) {
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
   sync_driver::SyncService* sync_service =
@@ -38,36 +37,15 @@
       password_bubble_experiment::ShouldShowSavePromptFirstRunExperience(
           sync_service, profile->GetPrefs());
   InfoBarService::FromWebContents(web_contents)
-      ->AddInfoBar(CreateSavePasswordInfoBar(
-          make_scoped_ptr(new SavePasswordInfoBarDelegate(
-              web_contents, std::move(form_to_save), uma_histogram_suffix,
-              is_smartlock_branding_enabled,
-              should_show_first_run_experience))));
+      ->AddInfoBar(CreateSavePasswordInfoBar(make_scoped_ptr(
+          new SavePasswordInfoBarDelegate(web_contents, std::move(form_to_save),
+                                          is_smartlock_branding_enabled,
+                                          should_show_first_run_experience))));
 }
 
 SavePasswordInfoBarDelegate::~SavePasswordInfoBarDelegate() {
-  UMA_HISTOGRAM_ENUMERATION("PasswordManager.InfoBarResponse",
-                            infobar_response_,
-                            password_manager::metrics_util::NUM_RESPONSE_TYPES);
-
   password_manager::metrics_util::LogUIDismissalReason(infobar_response_);
 
-  // The shortest period for which the prompt needs to live, so that we don't
-  // consider it killed prematurely, as might happen, e.g., if a pre-rendered
-  // page gets swapped in (and the current WebContents is destroyed).
-  const base::TimeDelta kMinimumPromptDisplayTime =
-      base::TimeDelta::FromSeconds(1);
-
-  if (!uma_histogram_suffix_.empty()) {
-    password_manager::metrics_util::LogUMAHistogramEnumeration(
-        "PasswordManager.SavePasswordPromptResponse_" + uma_histogram_suffix_,
-        infobar_response_,
-        password_manager::metrics_util::NUM_RESPONSE_TYPES);
-    password_manager::metrics_util::LogUMAHistogramBoolean(
-        "PasswordManager.SavePasswordPromptDisappearedQuickly_" +
-            uma_histogram_suffix_,
-        timer_.Elapsed() < kMinimumPromptDisplayTime);
-  }
   if (should_show_first_run_experience_) {
     Profile* profile =
         Profile::FromBrowserContext(web_contents_->GetBrowserContext());
@@ -79,20 +57,13 @@
 SavePasswordInfoBarDelegate::SavePasswordInfoBarDelegate(
     content::WebContents* web_contents,
     scoped_ptr<password_manager::PasswordFormManager> form_to_save,
-    const std::string& uma_histogram_suffix,
     bool is_smartlock_branding_enabled,
     bool should_show_first_run_experience)
     : PasswordManagerInfoBarDelegate(),
       form_to_save_(std::move(form_to_save)),
-      infobar_response_(password_manager::metrics_util::NO_RESPONSE),
-      uma_histogram_suffix_(uma_histogram_suffix),
+      infobar_response_(password_manager::metrics_util::NO_DIRECT_INTERACTION),
       should_show_first_run_experience_(should_show_first_run_experience),
       web_contents_(web_contents) {
-  if (!uma_histogram_suffix_.empty()) {
-    password_manager::metrics_util::LogUMAHistogramBoolean(
-        "PasswordManager.SavePasswordPromptDisplayed_" + uma_histogram_suffix_,
-        true);
-  }
   base::string16 message;
   gfx::Range message_link_range = gfx::Range();
   PasswordTittleType type =
@@ -121,7 +92,7 @@
 
 void SavePasswordInfoBarDelegate::InfoBarDismissed() {
   DCHECK(form_to_save_.get());
-  infobar_response_ = password_manager::metrics_util::INFOBAR_DISMISSED;
+  infobar_response_ = password_manager::metrics_util::CLICKED_CANCEL;
 }
 
 base::string16 SavePasswordInfoBarDelegate::GetButtonLabel(
@@ -134,13 +105,13 @@
 bool SavePasswordInfoBarDelegate::Accept() {
   DCHECK(form_to_save_.get());
   form_to_save_->Save();
-  infobar_response_ = password_manager::metrics_util::REMEMBER_PASSWORD;
+  infobar_response_ = password_manager::metrics_util::CLICKED_SAVE;
   return true;
 }
 
 bool SavePasswordInfoBarDelegate::Cancel() {
   DCHECK(form_to_save_.get());
   form_to_save_->PermanentlyBlacklist();
-  infobar_response_ = password_manager::metrics_util::NEVER_REMEMBER_PASSWORD;
+  infobar_response_ = password_manager::metrics_util::CLICKED_NEVER;
   return true;
 }
diff --git a/chrome/browser/password_manager/save_password_infobar_delegate.h b/chrome/browser/password_manager/save_password_infobar_delegate.h
index 5de8f89..db7a3d8 100644
--- a/chrome/browser/password_manager/save_password_infobar_delegate.h
+++ b/chrome/browser/password_manager/save_password_infobar_delegate.h
@@ -32,14 +32,10 @@
  public:
   // If we won't be showing the one-click signin infobar, creates a save
   // password infobar and delegate and adds the infobar to the InfoBarService
-  // for |web_contents|.  |uma_histogram_suffix| is empty, or one of the
-  // "group_X" suffixes used in the histogram names for infobar usage reporting;
-  // if empty, the usage is not reported, otherwise the suffix is used to choose
-  // the right histogram.
+  // for |web_contents|.
   static void Create(
       content::WebContents* web_contents,
-      scoped_ptr<password_manager::PasswordFormManager> form_to_save,
-      const std::string& uma_histogram_suffix);
+      scoped_ptr<password_manager::PasswordFormManager> form_to_save);
 
   ~SavePasswordInfoBarDelegate() override;
 
@@ -57,7 +53,6 @@
   SavePasswordInfoBarDelegate(
       content::WebContents* web_contents,
       scoped_ptr<password_manager::PasswordFormManager> form_to_save,
-      const std::string& uma_histogram_suffix,
       bool is_smartlock_branding_enabled,
       bool should_show_first_run_experience);
 
@@ -67,16 +62,12 @@
   scoped_ptr<password_manager::PasswordFormManager> form_to_save_;
 
   // Used to track the results we get from the info bar.
-  password_manager::metrics_util::ResponseType infobar_response_;
+  password_manager::metrics_util::UIDismissalReason infobar_response_;
 
   // Measures the "Save password?" prompt lifetime. Used to report an UMA
   // signal.
   base::ElapsedTimer timer_;
 
-  // The group name corresponding to the domain name of |form_to_save_| if the
-  // form is on a monitored domain. Otherwise, an empty string.
-  const std::string uma_histogram_suffix_;
-
   // Records source from where infobar was triggered.
   // Infobar appearance (message, buttons) depends on value of this parameter.
   password_manager::CredentialSourceType source_type_;
diff --git a/chrome/browser/password_manager/save_password_infobar_delegate_unittest.cc b/chrome/browser/password_manager/save_password_infobar_delegate_unittest.cc
index 2cda586f..5993b99 100644
--- a/chrome/browser/password_manager/save_password_infobar_delegate_unittest.cc
+++ b/chrome/browser/password_manager/save_password_infobar_delegate_unittest.cc
@@ -49,7 +49,6 @@
       bool should_show_first_run_experience)
       : SavePasswordInfoBarDelegate(web_contents,
                                     std::move(form_to_save),
-                                    std::string(),
                                     true /* is_smartlock_branding_enabled */,
                                     should_show_first_run_experience) {}
 
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 57f2fd3..aaea4da2 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -45,6 +45,7 @@
 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ssl/chrome_expect_ct_reporter.h"
 #include "chrome/browser/ui/search/new_tab_page_interceptor_service.h"
 #include "chrome/browser/ui/search/new_tab_page_interceptor_service_factory.h"
 #include "chrome/common/chrome_paths.h"
@@ -663,6 +664,10 @@
     transport_security_state_->SetReportSender(nullptr);
   certificate_report_sender_.reset();
 
+  if (transport_security_state_)
+    transport_security_state_->SetExpectCTReporter(nullptr);
+  expect_ct_reporter_.reset();
+
   // TODO(ajwong): These AssertNoURLRequests() calls are unnecessary since they
   // are already done in the URLRequestContext destructor.
   if (main_request_context_)
@@ -1069,6 +1074,10 @@
       net::CertificateReportSender::DO_NOT_SEND_COOKIES));
   transport_security_state_->SetReportSender(certificate_report_sender_.get());
 
+  expect_ct_reporter_.reset(
+      new ChromeExpectCTReporter(main_request_context_.get()));
+  transport_security_state_->SetExpectCTReporter(expect_ct_reporter_.get());
+
   // Take ownership over these parameters.
   cookie_settings_ = profile_params_->cookie_settings;
   host_content_settings_map_ = profile_params_->host_content_settings_map;
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index afe106a..92c9bf5b 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -39,6 +39,7 @@
 class ChromeHttpUserAgentSettings;
 class ChromeNetworkDelegate;
 class ChromeURLRequestContextGetter;
+class ChromeExpectCTReporter;
 class HostContentSettingsMap;
 class MediaDeviceIDSalt;
 class ProtocolHandlerRegistry;
@@ -545,6 +546,7 @@
   mutable scoped_ptr<net::ProxyService> proxy_service_;
   mutable scoped_ptr<net::TransportSecurityState> transport_security_state_;
   mutable scoped_ptr<net::CTVerifier> cert_transparency_verifier_;
+  mutable scoped_ptr<ChromeExpectCTReporter> expect_ct_reporter_;
   mutable scoped_ptr<net::HttpServerProperties>
       http_server_properties_;
 #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
index ae9fef38..757ec01 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
@@ -200,8 +200,10 @@
  * @return {boolean}
  */
 AutomationPredicate.container = function(node) {
+  if (node.role == RoleType.rootWebArea)
+    return !node.parent || node.parent.root.role != RoleType.rootWebArea;
+
   return node.role == RoleType.toolbar ||
-      node.role == RoleType.rootWebArea ||
       node.role == RoleType.window;
 };
 
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
index d8f3338..87f0321 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
@@ -66,7 +66,14 @@
       <option>grape</option>
       <option> banana</option>
     </select>
-  */}
+  */},
+
+  iframesDoc: function() {/*!
+    <p>start</p>
+    <button>Before</button>
+    <iframe srcdoc="<button>Inside</button>"></iframe>
+    <button>After</button>
+  */},
 };
 
 /** Tests that ChromeVox classic is in this context. */
@@ -586,3 +593,40 @@
         .replay();
   });
 });
+
+/** Tests navigating into and out of iframes.. */
+TEST_F('BackgroundTest', 'ForwardNavigationThroughIframes', function() {
+  var mockFeedback = this.createMockFeedback();
+
+  var runTestIfIframeIsLoaded = function(rootNode) {
+    // Return if the iframe hasn't loaded yet.
+    var iframe = rootNode.find({role: 'iframe'});
+    var childDoc = iframe.firstChild;
+    if (childDoc && childDoc.children.length == 0) {
+      return;
+    }
+
+    var doCmd = this.doCmd.bind(this);
+
+    mockFeedback.expectSpeech('start').expectBraille('start');
+
+    mockFeedback.call(doCmd('nextButton'))
+        .expectSpeech('Before', 'Button');
+    mockFeedback.call(doCmd('nextButton'))
+        .expectSpeech('Inside', 'Button');
+    mockFeedback.call(doCmd('nextButton'))
+        .expectSpeech('After', 'Button');
+
+    mockFeedback.replay();
+  }.bind(this);
+
+  this.runWithLoadedTree(this.iframesDoc, function(rootNode) {
+    chrome.automation.getDesktop(function(desktopNode) {
+      runTestIfIframeIsLoaded(rootNode);
+
+      desktopNode.addEventListener('loadComplete', function(evt) {
+        runTestIfIframeIsLoaded(rootNode);
+      }, true);      
+    });
+  });
+});
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css
index ea976da..a680b39 100644
--- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css
+++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css
@@ -191,7 +191,7 @@
   --paper-input-container-label: {
     font-size: 12px;
   };
-  -webkit-padding-end: 31px;
+  -webkit-margin-end: 31px;
   box-sizing: border-box;
 }
 
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
index 7f6114d..eddec3c 100644
--- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
+++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
@@ -1236,14 +1236,26 @@
     // The provider will handle sending an issue for a failed route request.
     if (!route) {
       this.resetRouteCreationProperties_(false);
+      this.fire('report-resolved-route', {
+        outcome: media_router.MediaRouterRouteCreationOutcome.FAILURE_NO_ROUTE
+      });
       return;
     }
 
     // Check that |sinkId| exists and corresponds to |currentLaunchingSinkId_|.
-    // TODO(apacible): Add metrics for when |route| is resolved for an invalid
-    // |sinkId|. See http://crbug.com/584993
-    if (!this.sinkMap_[sinkId] || this.currentLaunchingSinkId_ != sinkId)
+    if (!this.sinkMap_[sinkId] || this.currentLaunchingSinkId_ != sinkId) {
+      this.fire('report-resolved-route', {
+        outcome:
+            media_router.MediaRouterRouteCreationOutcome.FAILURE_INVALID_SINK
+      });
       return;
+    }
+
+    // Regardless of whether the route is for display, it was resolved
+    // successfully.
+    this.fire('report-resolved-route', {
+      outcome: media_router.MediaRouterRouteCreationOutcome.SUCCESS
+    });
 
     if (isForDisplay) {
       this.showRouteDetails_(route);
diff --git a/chrome/browser/resources/media_router/media_router.js b/chrome/browser/resources/media_router/media_router.js
index 394e9bc..8f1c6ea2 100644
--- a/chrome/browser/resources/media_router/media_router.js
+++ b/chrome/browser/resources/media_router/media_router.js
@@ -48,6 +48,8 @@
     container.addEventListener('report-sink-click-time',
                                onSinkClickTimeReported);
     container.addEventListener('report-sink-count', onSinkCountReported);
+    container.addEventListener('report-resolved-route',
+                               onReportRouteCreationOutcome);
     container.addEventListener('show-initial-state', onShowInitialState);
     container.addEventListener('sink-click', onSinkClick);
     container.addEventListener('start-casting-to-route-click',
@@ -249,6 +251,23 @@
   }
 
   /**
+   * Reports success or the type of failure for route creation response.
+   * Called when the route is resolved; either the route creation was a success
+   * or if there was no route or the route's corresponding sink is invalid;
+   * either the sink does not exist or was not the sink we were looking for.
+   *
+   * @param {!Event} event
+   * Parameters in |event|.detail:
+   *   outcome - the outcome of a create route response.
+   *
+   */
+  function onReportRouteCreationOutcome(event) {
+    /** @type {{outcome: number}} */
+    var detail = event.detail;
+    media_router.browserApi.reportRouteCreationOutcome(detail.outcome);
+  }
+
+  /**
    * Reports the initial state of the dialog after it is opened.
    * Called after initial data is populated.
    *
diff --git a/chrome/browser/resources/media_router/media_router_data.js b/chrome/browser/resources/media_router/media_router_data.js
index 729d0a4..f7e0a73 100644
--- a/chrome/browser/resources/media_router/media_router_data.js
+++ b/chrome/browser/resources/media_router/media_router_data.js
@@ -30,6 +30,17 @@
 media_router.KEYCODE_ESC = 27;
 
 /**
+ * This corresponds to the C++ MediaRouterMetrics
+ * MediaRouterRouteCreationOutcome.
+ * @enum {number}
+ */
+media_router.MediaRouterRouteCreationOutcome = {
+  SUCCESS: 0,
+  FAILURE_NO_ROUTE: 1,
+  FAILURE_INVALID_SINK: 2,
+};
+
+/**
  * This corresponds to the C++ MediaRouterMetrics MediaRouterUserAction.
  * @enum {number}
  */
diff --git a/chrome/browser/resources/media_router/media_router_ui_interface.js b/chrome/browser/resources/media_router/media_router_ui_interface.js
index a566dfe..23fac9c62 100644
--- a/chrome/browser/resources/media_router/media_router_ui_interface.js
+++ b/chrome/browser/resources/media_router/media_router_ui_interface.js
@@ -284,6 +284,15 @@
   }
 
   /**
+   * Reports the outcome of a create route response.
+   *
+   * @param {number} outcome
+   */
+  function reportRouteCreationOutcome(outcome) {
+    chrome.send('reportRouteCreationOutcome', [outcome]);
+  }
+
+  /**
    * Reports the cast mode that the user selected.
    *
    * @param {number} castModeType
@@ -353,8 +362,9 @@
     reportInitialAction: reportInitialAction,
     reportInitialState: reportInitialState,
     reportNavigateToView: reportNavigateToView,
-    reportSelectedCastMode: reportSelectedCastMode,
     reportRouteCreation: reportRouteCreation,
+    reportRouteCreationOutcome: reportRouteCreationOutcome,
+    reportSelectedCastMode: reportSelectedCastMode,
     reportSinkCount: reportSinkCount,
     reportTimeToClickSink: reportTimeToClickSink,
     reportTimeToInitialActionClose: reportTimeToInitialActionClose,
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter.cc b/chrome/browser/ssl/chrome_expect_ct_reporter.cc
new file mode 100644
index 0000000..f6e0175
--- /dev/null
+++ b/chrome/browser/ssl/chrome_expect_ct_reporter.cc
@@ -0,0 +1,25 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ssl/chrome_expect_ct_reporter.h"
+
+#include <string>
+
+#include "net/url_request/certificate_report_sender.h"
+
+ChromeExpectCTReporter::ChromeExpectCTReporter(
+    net::URLRequestContext* request_context)
+    : report_sender_(new net::CertificateReportSender(
+          request_context,
+          net::CertificateReportSender::DO_NOT_SEND_COOKIES)) {}
+
+ChromeExpectCTReporter::~ChromeExpectCTReporter() {}
+
+void ChromeExpectCTReporter::OnExpectCTFailed(
+    const net::HostPortPair& host_port_pair,
+    const GURL& report_uri,
+    const net::SSLInfo& ssl_info) {
+  // TODO(estark): build and send a report about the policy
+  // violation. https://crbug.com/568806
+}
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter.h b/chrome/browser/ssl/chrome_expect_ct_reporter.h
new file mode 100644
index 0000000..15e74da
--- /dev/null
+++ b/chrome/browser/ssl/chrome_expect_ct_reporter.h
@@ -0,0 +1,38 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SSL_CHROME_EXPECT_CT_REPORTER_H_
+#define CHROME_BROWSER_SSL_CHROME_EXPECT_CT_REPORTER_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/http/transport_security_state.h"
+
+namespace net {
+class CertificateReportSender;
+class URLRequestContext;
+}  // namespace net
+
+// This class monitors for violations of CT policy and sends reports
+// about failures for sites that have opted in. Must be deleted before
+// the URLRequestContext that is passed to the constructor, so that it
+// can cancel its requests.
+class ChromeExpectCTReporter
+    : public net::TransportSecurityState::ExpectCTReporter {
+ public:
+  explicit ChromeExpectCTReporter(net::URLRequestContext* request_context);
+  ~ChromeExpectCTReporter() override;
+
+  // net::ExpectCTReporter:
+  void OnExpectCTFailed(const net::HostPortPair& host_port_pair,
+                        const GURL& report_uri,
+                        const net::SSLInfo& ssl_info) override;
+
+ private:
+  scoped_ptr<net::CertificateReportSender> report_sender_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeExpectCTReporter);
+};
+
+#endif  // CHROME_BROWSER_SSL_CHROME_EXPECT_CT_REPORTER_H_
diff --git a/chrome/browser/sync_file_system/drive_backend/callback_helper.h b/chrome/browser/sync_file_system/drive_backend/callback_helper.h
index 80a2e44..c220571 100644
--- a/chrome/browser/sync_file_system/drive_backend/callback_helper.h
+++ b/chrome/browser/sync_file_system/drive_backend/callback_helper.h
@@ -22,15 +22,12 @@
 namespace internal {
 
 template <typename T>
-typename std::enable_if<base::internal::IsMoveOnlyType<T>::value,
-                        base::internal::PassedWrapper<T>>::type
-RebindForward(T& t) {
+base::internal::PassedWrapper<scoped_ptr<T>> RebindForward(scoped_ptr<T>& t) {
   return base::Passed(&t);
 }
 
 template <typename T>
-typename std::enable_if<!base::internal::IsMoveOnlyType<T>::value, T&>::type
-RebindForward(T& t) {
+T& RebindForward(T& t) {
   return t;
 }
 
@@ -72,8 +69,7 @@
   static void Run(CallbackHolder<void(Args...)>* holder, Args... args) {
     holder->task_runner()->PostTask(
         holder->from_here(),
-        base::Bind(holder->callback(),
-                   RebindForward(args)...));
+        base::Bind(holder->callback(), RebindForward(args)...));
   }
 };
 
diff --git a/chrome/browser/sync_file_system/drive_backend/callback_tracker_internal.h b/chrome/browser/sync_file_system/drive_backend/callback_tracker_internal.h
index 0fb9eb4..4f8e445 100644
--- a/chrome/browser/sync_file_system/drive_backend/callback_tracker_internal.h
+++ b/chrome/browser/sync_file_system/drive_backend/callback_tracker_internal.h
@@ -5,8 +5,9 @@
 #ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_TRACKER_INTERNAL_H_
 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_CALLBACK_TRACKER_INTERNAL_H_
 
+#include <utility>
+
 #include "base/callback.h"
-#include "base/callback_internal.h"
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -44,7 +45,7 @@
                   Args... args) {
     scoped_ptr<AbortHelper> deleter = AbortHelper::TakeOwnership(abort_helper);
     if (deleter) {
-      callback.Run(base::internal::CallbackForward(args)...);
+      callback.Run(std::forward<Args>(args)...);
     }
   }
 };
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc b/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc
index 006c6813..b923b98 100644
--- a/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc
@@ -55,7 +55,7 @@
 void SetValueAndCallClosure(const base::Closure& closure,
                             T* arg_out,
                             T arg) {
-  *arg_out = base::internal::CallbackForward(arg);
+  *arg_out = std::forward<T>(arg);
   closure.Run();
 }
 
diff --git a/chrome/browser/sync_file_system/sync_file_system_test_util.cc b/chrome/browser/sync_file_system/sync_file_system_test_util.cc
index 772cc13..2e5a0e4 100644
--- a/chrome/browser/sync_file_system/sync_file_system_test_util.cc
+++ b/chrome/browser/sync_file_system/sync_file_system_test_util.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
 
+#include <utility>
+
 #include "base/memory/scoped_ptr.h"
 #include "base/run_loop.h"
 #include "chrome/browser/sync_file_system/remote_file_sync_service.h"
@@ -36,7 +38,7 @@
 void ReceiveResult1(bool* done, Arg* arg_out, Param arg) {
   EXPECT_FALSE(*done);
   *done = true;
-  *arg_out = base::internal::CallbackForward(arg);
+  *arg_out = std::forward<Param>(arg);
 }
 
 template <typename Arg>
diff --git a/chrome/browser/sync_file_system/sync_file_system_test_util.h b/chrome/browser/sync_file_system/sync_file_system_test_util.h
index 346b365b..26bafaa 100644
--- a/chrome/browser/sync_file_system/sync_file_system_test_util.h
+++ b/chrome/browser/sync_file_system/sync_file_system_test_util.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_SYNC_FILE_SYSTEM_TEST_UTIL_H_
 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_SYNC_FILE_SYSTEM_TEST_UTIL_H_
 
+#include <utility>
 #include <vector>
 
 #include "base/bind.h"
@@ -44,8 +45,8 @@
                     Param2 arg2) {
   EXPECT_FALSE(*done);
   *done = true;
-  *arg1_out = base::internal::CallbackForward(arg1);
-  *arg2_out = base::internal::CallbackForward(arg2);
+  *arg1_out = std::forward<Param1>(arg1);
+  *arg2_out = std::forward<Param2>(arg2);
 }
 
 template <typename R>
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
index 4a80bbd..1731bb3 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
@@ -38,8 +38,8 @@
   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
       [[CustomConstrainedWindowSheet alloc]
           initWithCustomWindow:[sheet_delegate_ window]]);
-  constrained_window_.reset(
-      new ConstrainedWindowMac(this, delegate_->GetWebContents(), sheet));
+  constrained_window_ =
+      CreateAndShowWebModalDialogMac(this, delegate_->GetWebContents(), sheet);
   [sheet_delegate_ show];
 }
 
diff --git a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm
index 2a9d770..b4f949e 100644
--- a/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm
+++ b/chrome/browser/ui/cocoa/autofill/card_unmask_prompt_view_bridge.mm
@@ -87,8 +87,8 @@
   [window setContentView:[view_controller_ view]];
   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
       [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]);
-  constrained_window_.reset(
-      new ConstrainedWindowMac(this, web_contents_, sheet));
+  constrained_window_ =
+      CreateAndShowWebModalDialogMac(this, web_contents_, sheet);
 }
 
 void CardUnmaskPromptViewBridge::ControllerGone() {
diff --git a/chrome/browser/ui/cocoa/certificate_viewer_mac.mm b/chrome/browser/ui/cocoa/certificate_viewer_mac.mm
index 5c41b94f..1adb0f1 100644
--- a/chrome/browser/ui/cocoa/certificate_viewer_mac.mm
+++ b/chrome/browser/ui/cocoa/certificate_viewer_mac.mm
@@ -134,8 +134,8 @@
   panel_.reset([[SFCertificatePanel alloc] init]);
   [panel_ setPolicies:(id) policies.get()];
 
-  constrainedWindow_.reset(
-      new ConstrainedWindowMac(observer_.get(), webContents, self));
+  constrainedWindow_ =
+      CreateAndShowWebModalDialogMac(observer_.get(), webContents, self);
 }
 
 - (NSWindow*)overlayWindow {
@@ -189,6 +189,10 @@
   // NOOP
 }
 
+- (void)resizeWithNewSize:(NSSize)preferredSize {
+  // NOOP
+}
+
 - (NSWindow*)sheetWindow {
   return panel_;
 }
diff --git a/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm b/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
index 0ce4df8d..74206ed2 100644
--- a/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
+++ b/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
@@ -11,7 +11,11 @@
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h"
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.h"
+#include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
+#include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "ui/base/cocoa/window_size_constants.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/web_dialogs/web_dialog_delegate.h"
 #include "ui/web_dialogs/web_dialog_ui.h"
@@ -23,19 +27,61 @@
 
 namespace {
 
+class ConstrainedWebDialogDelegateMac;
+
+// This class is to trigger a resize to the dialog window when
+// ResizeDueToAutoResize() is invoked.
+class WebDialogWebContentsDelegateMac
+    : public ui::WebDialogWebContentsDelegate {
+ public:
+  WebDialogWebContentsDelegateMac(content::BrowserContext* browser_context,
+                                  content::WebContentsObserver* observer,
+                                  ConstrainedWebDialogDelegateBase* delegate)
+      : ui::WebDialogWebContentsDelegate(browser_context,
+                                         new ChromeWebContentsHandler()),
+        observer_(observer),
+        delegate_(delegate) {
+  }
+  ~WebDialogWebContentsDelegateMac() override {}
+
+  void ResizeDueToAutoResize(content::WebContents* source,
+                             const gfx::Size& preferred_size) override {
+    if (!observer_->web_contents())
+      return;
+    delegate_->ResizeToGivenSize(preferred_size);
+  }
+
+ private:
+  // These members must outlive the instance.
+  content::WebContentsObserver* const observer_;
+  ConstrainedWebDialogDelegateBase* delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebDialogWebContentsDelegateMac);
+};
+
 class ConstrainedWebDialogDelegateMac
     : public ConstrainedWebDialogDelegateBase {
  public:
   ConstrainedWebDialogDelegateMac(
       content::BrowserContext* browser_context,
-      WebDialogDelegate* delegate)
-      : ConstrainedWebDialogDelegateBase(browser_context, delegate, NULL) {}
+      WebDialogDelegate* delegate,
+      content::WebContentsObserver* observer)
+      : ConstrainedWebDialogDelegateBase(browser_context, delegate,
+          new WebDialogWebContentsDelegateMac(browser_context, observer,
+                                              this)) {}
 
   // WebDialogWebContentsDelegate interface.
   void CloseContents(WebContents* source) override {
     window_->CloseWebContentsModalDialog();
   }
 
+  // ConstrainedWebDialogDelegateBase:
+  void ResizeToGivenSize(const gfx::Size size) override {
+    NSSize updated_preferred_size = NSMakeSize(size.width(),
+                                               size.height());
+    [window_->sheet() resizeWithNewSize:updated_preferred_size];
+  }
+
   void set_window(ConstrainedWindowMac* window) { window_ = window; }
   ConstrainedWindowMac* window() const { return window_; }
 
@@ -50,13 +96,16 @@
 
 class ConstrainedWebDialogDelegateViewMac :
     public ConstrainedWindowMacDelegate,
-    public ConstrainedWebDialogDelegate {
+    public ConstrainedWebDialogDelegate,
+    public content::WebContentsObserver {
 
  public:
   ConstrainedWebDialogDelegateViewMac(
       content::BrowserContext* browser_context,
       WebDialogDelegate* delegate,
-      content::WebContents* web_contents);
+      content::WebContents* web_contents,
+      const gfx::Size& min_size,
+      const gfx::Size& max_size);
   ~ConstrainedWebDialogDelegateViewMac() override {}
 
   // ConstrainedWebDialogDelegate interface
@@ -75,16 +124,37 @@
   gfx::NativeWindow GetNativeDialog() override { return window_; }
   WebContents* GetWebContents() override { return impl_->GetWebContents(); }
   gfx::Size GetMinimumSize() const override {
-    NOTIMPLEMENTED();
-    return gfx::Size();
+    return min_size_;
   }
   gfx::Size GetMaximumSize() const override {
-    NOTIMPLEMENTED();
-    return gfx::Size();
+    return max_size_;
   }
   gfx::Size GetPreferredSize() const override {
-    NOTIMPLEMENTED();
-    return gfx::Size();
+    gfx::Size size;
+    if (!impl_->closed_via_webui()) {
+      NSRect frame = [window_ frame];
+      size = gfx::Size(frame.size.width, frame.size.height);
+    }
+    return size;
+  }
+
+  // content::WebContentsObserver:
+  void RenderViewCreated(content::RenderViewHost* render_view_host) override {
+    if (IsDialogAutoResizable())
+      EnableAutoResize();
+  }
+  void RenderViewHostChanged(content::RenderViewHost* old_host,
+                             content::RenderViewHost* new_host) override {
+    if (IsDialogAutoResizable())
+      EnableAutoResize();
+  }
+  void DocumentOnLoadCompletedInMainFrame() override {
+    if (!IsDialogAutoResizable())
+      return;
+
+    EnableAutoResize();
+    if (GetWebContents())
+      constrained_window_->ShowWebContentsModalDialog();
   }
 
   // ConstrainedWindowMacDelegate interface
@@ -95,25 +165,56 @@
   }
 
  private:
+  void EnableAutoResize() {
+    if (!GetWebContents())
+      return;
+
+    content::RenderViewHost* render_view_host =
+        GetWebContents()->GetRenderViewHost();
+    render_view_host->EnableAutoResize(min_size_, max_size_);
+  }
+
+  // Whether or not the dialog is autoresizable is determined based on whether
+  // |max_size_| was specified.
+  bool IsDialogAutoResizable() {
+    return !max_size_.IsEmpty();
+  }
+
   scoped_ptr<ConstrainedWebDialogDelegateMac> impl_;
   scoped_ptr<ConstrainedWindowMac> constrained_window_;
   base::scoped_nsobject<NSWindow> window_;
 
+  // Minimum and maximum sizes to determine dialog bounds for auto-resizing.
+  const gfx::Size min_size_;
+  const gfx::Size max_size_;
+
   DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewMac);
 };
 
 ConstrainedWebDialogDelegateViewMac::ConstrainedWebDialogDelegateViewMac(
     content::BrowserContext* browser_context,
     WebDialogDelegate* delegate,
-    content::WebContents* web_contents)
-    : impl_(new ConstrainedWebDialogDelegateMac(browser_context, delegate)) {
+    content::WebContents* web_contents,
+    const gfx::Size& min_size,
+    const gfx::Size& max_size)
+    : content::WebContentsObserver(web_contents),
+      impl_(new ConstrainedWebDialogDelegateMac(browser_context, delegate,
+            this)),
+      min_size_(min_size),
+      max_size_(max_size) {
+  if (IsDialogAutoResizable())
+    Observe(GetWebContents());
+
   // Create a window to hold web_contents in the constrained sheet:
   gfx::Size size;
   delegate->GetDialogSize(&size);
-  NSRect frame = NSMakeRect(0, 0, size.width(), size.height());
+  // The window size for autoresizing dialogs will be determined at a later
+  // time.
+  NSRect frame = IsDialogAutoResizable() ? ui::kWindowSizeDeterminedLater :
+      NSMakeRect(0, 0, size.width(), size.height());
 
-  window_.reset(
-      [[ConstrainedWindowCustomWindow alloc] initWithContentRect:frame]);
+  window_.reset([[ConstrainedWindowCustomWindow alloc]
+                initWithContentRect:frame]);
   [GetWebContents()->GetNativeView() setFrame:frame];
   [GetWebContents()->GetNativeView() setAutoresizingMask:
       NSViewWidthSizable|NSViewHeightSizable];
@@ -122,8 +223,14 @@
   base::scoped_nsobject<WebDialogConstrainedWindowSheet> sheet(
       [[WebDialogConstrainedWindowSheet alloc] initWithCustomWindow:window_
                                                   webDialogDelegate:delegate]);
-  constrained_window_.reset(new ConstrainedWindowMac(
-      this, web_contents, sheet));
+
+  if (IsDialogAutoResizable()) {
+    constrained_window_ = CreateWebModalDialogMac(
+        this, web_contents, sheet);
+  } else {
+    constrained_window_ = CreateAndShowWebModalDialogMac(
+        this, web_contents, sheet);
+  }
 
   impl_->set_window(constrained_window_.get());
 }
@@ -135,6 +242,23 @@
   // Deleted when the dialog closes.
   ConstrainedWebDialogDelegateViewMac* constrained_delegate =
       new ConstrainedWebDialogDelegateViewMac(
-          browser_context, delegate, web_contents);
+          browser_context, delegate, web_contents,
+          gfx::Size(), gfx::Size());
+  return constrained_delegate;
+}
+
+ConstrainedWebDialogDelegate* ShowConstrainedWebDialogWithAutoResize(
+    content::BrowserContext* browser_context,
+    WebDialogDelegate* delegate,
+    content::WebContents* web_contents,
+    const gfx::Size& min_size,
+    const gfx::Size& max_size) {
+  DCHECK(!min_size.IsEmpty());
+  DCHECK(!max_size.IsEmpty());
+  // Deleted when the dialog closes.
+  ConstrainedWebDialogDelegateViewMac* constrained_delegate =
+      new ConstrainedWebDialogDelegateViewMac(
+          browser_context, delegate, web_contents,
+          min_size, max_size);
   return constrained_delegate;
 }
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm
index aac59467..ab67fc6 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.mm
@@ -73,6 +73,10 @@
   [customWindow_ setFrameOrigin:origin];
 }
 
+- (void)resizeWithNewSize:(NSSize)size {
+  // NOOP
+}
+
 - (NSWindow*)sheetWindow {
   return customWindow_;
 }
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h
index e3d981e..33aa9dd4 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h
@@ -7,6 +7,9 @@
 
 #import <Cocoa/Cocoa.h>
 
+#include "base/mac/scoped_nsobject.h"
+#include "components/web_modal/web_contents_modal_dialog_manager.h"
+
 namespace content {
 class WebContents;
 }
@@ -21,6 +24,18 @@
   virtual void OnConstrainedWindowClosed(ConstrainedWindowMac* window) = 0;
 };
 
+// Creates a ConstrainedWindowMac, shows the dialog, and returns it.
+scoped_ptr<ConstrainedWindowMac> CreateAndShowWebModalDialogMac(
+    ConstrainedWindowMacDelegate* delegate,
+    content::WebContents* web_contents,
+    id<ConstrainedWindowSheet> sheet);
+
+// Creates a ConstrainedWindowMac and returns it.
+scoped_ptr<ConstrainedWindowMac> CreateWebModalDialogMac(
+    ConstrainedWindowMacDelegate* delegate,
+    content::WebContents* web_contents,
+    id<ConstrainedWindowSheet> sheet);
+
 // Constrained window implementation for Mac.
 // Normally an instance of this class is owned by the delegate. The delegate
 // should delete the instance when the window is closed.
@@ -31,6 +46,9 @@
                        id<ConstrainedWindowSheet> sheet);
   ~ConstrainedWindowMac();
 
+  // Shows the constrained window.
+  void ShowWebContentsModalDialog();
+
   // Closes the constrained window.
   void CloseWebContentsModalDialog();
 
@@ -38,13 +56,24 @@
   void set_manager(SingleWebContentsDialogManagerCocoa* manager) {
     manager_ = manager;
   }
+  id<ConstrainedWindowSheet> sheet() const { return sheet_.get(); }
 
   // Called by |manager_| when the dialog is closing.
   void OnDialogClosing();
 
+  // Whether or not the dialog was shown. If the dialog is auto-resizable, it
+  // is hidden until its WebContents initially loads.
+  bool DialogWasShown();
+
+  // Gets the dialog manager for |web_contents_|.
+  web_modal::WebContentsModalDialogManager* GetDialogManager();
+
  private:
   ConstrainedWindowMacDelegate* delegate_;  // weak, owns us.
   SingleWebContentsDialogManagerCocoa* manager_;  // weak, owned by WCMDM.
+  content::WebContents* web_contents_;  // weak, owned by dialog initiator.
+  base::scoped_nsprotocol<id<ConstrainedWindowSheet>> sheet_;
+  scoped_ptr<SingleWebContentsDialogManagerCocoa> native_manager_;
 };
 
 #endif  // CHROME_BROWSER_UI_COCOA_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_MAC_
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
index 16f755c..683eb68 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
@@ -11,35 +11,59 @@
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h"
 #import "chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.h"
 #include "components/guest_view/browser/guest_view_base.h"
-#include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "content/public/browser/browser_thread.h"
 
 using web_modal::WebContentsModalDialogManager;
 
+scoped_ptr<ConstrainedWindowMac> CreateAndShowWebModalDialogMac(
+    ConstrainedWindowMacDelegate* delegate,
+    content::WebContents* web_contents,
+    id<ConstrainedWindowSheet> sheet) {
+  ConstrainedWindowMac* window =
+      new ConstrainedWindowMac(delegate, web_contents, sheet);
+  window->ShowWebContentsModalDialog();
+  return scoped_ptr<ConstrainedWindowMac>(window);
+}
+
+scoped_ptr<ConstrainedWindowMac> CreateWebModalDialogMac(
+    ConstrainedWindowMacDelegate* delegate,
+    content::WebContents* web_contents,
+    id<ConstrainedWindowSheet> sheet) {
+  return scoped_ptr<ConstrainedWindowMac>(
+      new ConstrainedWindowMac(delegate, web_contents, sheet));
+}
+
 ConstrainedWindowMac::ConstrainedWindowMac(
     ConstrainedWindowMacDelegate* delegate,
     content::WebContents* web_contents,
     id<ConstrainedWindowSheet> sheet)
-    : delegate_(delegate) {
+    : delegate_(delegate),
+      sheet_([sheet retain]) {
   DCHECK(sheet);
 
   // |web_contents| may be embedded within a chain of nested GuestViews. If it
   // is, follow the chain of embedders to the outermost WebContents and use it.
-  web_contents =
+  web_contents_ =
       guest_view::GuestViewBase::GetTopLevelWebContents(web_contents);
 
-  auto manager = WebContentsModalDialogManager::FromWebContents(web_contents);
-  scoped_ptr<SingleWebContentsDialogManagerCocoa> native_manager(
-      new SingleWebContentsDialogManagerCocoa(this, sheet, manager));
-  manager->ShowDialogWithManager([sheet sheetWindow],
-                                 std::move(native_manager));
+  native_manager_.reset(
+      new SingleWebContentsDialogManagerCocoa(this, sheet_.get(),
+                                              GetDialogManager()));
 }
 
 ConstrainedWindowMac::~ConstrainedWindowMac() {
   CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  native_manager_.reset();
   DCHECK(!manager_);
 }
 
+void ConstrainedWindowMac::ShowWebContentsModalDialog() {
+  scoped_ptr<SingleWebContentsDialogManagerCocoa> dialog_manager;
+  dialog_manager.reset(native_manager_.release());
+  GetDialogManager()->ShowDialogWithManager(
+      [sheet_.get() sheetWindow], std::move(dialog_manager));
+}
+
 void ConstrainedWindowMac::CloseWebContentsModalDialog() {
   if (manager_)
     manager_->Close();
@@ -49,3 +73,13 @@
   if (delegate_)
     delegate_->OnConstrainedWindowClosed(this);
 }
+
+bool ConstrainedWindowMac::DialogWasShown() {
+  // If the dialog was shown, |native_manager_| would have been released.
+  return !native_manager_;
+}
+
+WebContentsModalDialogManager* ConstrainedWindowMac::GetDialogManager() {
+  DCHECK(web_contents_);
+  return WebContentsModalDialogManager::FromWebContents(web_contents_);
+}
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm
index 8e6ceda..48e48a4 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm
@@ -79,14 +79,15 @@
 IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, ShowInInactiveTab) {
   // Show dialog in non active tab.
   NiceMock<ConstrainedWindowDelegateMock> delegate;
-  ConstrainedWindowMac dialog(&delegate, tab0_, sheet_);
+  scoped_ptr<ConstrainedWindowMac> dialog =
+      CreateAndShowWebModalDialogMac(&delegate, tab0_, sheet_);
   EXPECT_EQ(0.0, [sheet_window_ alphaValue]);
 
   // Switch to inactive tab.
   browser()->tab_strip_model()->ActivateTabAt(0, true);
   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
 
-  dialog.CloseWebContentsModalDialog();
+  dialog->CloseWebContentsModalDialog();
 }
 
 // If a tab has never been shown then the associated tab view for the web
@@ -105,7 +106,8 @@
 
   // Show dialog and verify that it's not visible yet.
   NiceMock<ConstrainedWindowDelegateMock> delegate;
-  ConstrainedWindowMac dialog(&delegate, tab2, sheet_);
+  scoped_ptr<ConstrainedWindowMac> dialog =
+      CreateAndShowWebModalDialogMac(&delegate, tab2, sheet_);
   EXPECT_FALSE([sheet_window_ isVisible]);
 
   // Activate the tab and verify that the constrained window is shown.
@@ -114,25 +116,27 @@
   EXPECT_TRUE([sheet_window_ isVisible]);
   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
 
-  dialog.CloseWebContentsModalDialog();
+  dialog->CloseWebContentsModalDialog();
 }
 
 // Test that adding a sheet disables tab dragging.
 IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, TabDragging) {
   NiceMock<ConstrainedWindowDelegateMock> delegate;
-  ConstrainedWindowMac dialog(&delegate, tab1_, sheet_);
+  scoped_ptr<ConstrainedWindowMac> dialog =
+      CreateAndShowWebModalDialogMac(&delegate, tab1_, sheet_);
 
   // Verify that the dialog disables dragging.
   EXPECT_TRUE([controller_ isTabDraggable:tab_view0_]);
   EXPECT_FALSE([controller_ isTabDraggable:tab_view1_]);
 
-  dialog.CloseWebContentsModalDialog();
+  dialog->CloseWebContentsModalDialog();
 }
 
 // Test that closing a browser window with a sheet works.
 IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, BrowserWindowClose) {
   NiceMock<ConstrainedWindowDelegateMock> delegate;
-  ConstrainedWindowMac dialog(&delegate, tab1_, sheet_);
+  scoped_ptr<ConstrainedWindowMac> dialog(
+      CreateAndShowWebModalDialogMac(&delegate, tab1_, sheet_));
   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
 
   // Close the browser window.
@@ -146,7 +150,8 @@
 // Test that closing a tab with a sheet works.
 IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, TabClose) {
   NiceMock<ConstrainedWindowDelegateMock> delegate;
-  ConstrainedWindowMac dialog(&delegate, tab1_, sheet_);
+  scoped_ptr<ConstrainedWindowMac> dialog(
+      CreateAndShowWebModalDialogMac(&delegate, tab1_, sheet_));
   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
 
   // Close the tab.
@@ -160,7 +165,8 @@
 // Test that the sheet is still visible after entering and exiting fullscreen.
 IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, BrowserWindowFullscreen) {
   NiceMock<ConstrainedWindowDelegateMock> delegate;
-  ConstrainedWindowMac dialog(&delegate, tab1_, sheet_);
+  scoped_ptr<ConstrainedWindowMac> dialog(
+      CreateAndShowWebModalDialogMac(&delegate, tab1_, sheet_));
   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
 
   // Toggle fullscreen twice: one for entering and one for exiting.
@@ -180,5 +186,5 @@
     EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
   }
 
-  dialog.CloseWebContentsModalDialog();
+  dialog->CloseWebContentsModalDialog();
 }
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h
index 4549556..cf24f7d 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h
@@ -24,6 +24,8 @@
 
 - (void)updateSheetPosition;
 
+- (void)resizeWithNewSize:(NSSize)size;
+
 @property(readonly, nonatomic) NSWindow* sheetWindow;
 
 @end
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm
index 05038cf..6566d21 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm
@@ -59,6 +59,10 @@
 - (void)updateSheetPosition {
 }
 
+- (void)resizeWithNewSize:(NSSize)size {
+  // NOOP
+}
+
 - (NSWindow*)sheetWindow {
   return [alert_ window];
 }
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.h b/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.h
index 57ba754..7c37e23 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.h
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.h
@@ -14,6 +14,7 @@
 // Represents a custom sheet for web dialog.
 @interface WebDialogConstrainedWindowSheet : CustomConstrainedWindowSheet {
  @private
+  NSSize current_size_;
   ui::WebDialogDelegate* web_dialog_delegate_;  // Weak.
 }
 
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.mm
index 3c71f00..775ae15 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.mm
@@ -22,9 +22,25 @@
   if (web_dialog_delegate_) {
     gfx::Size size;
     web_dialog_delegate_->GetDialogSize(&size);
-    [customWindow_ setContentSize:NSMakeSize(size.width(), size.height())];
+
+    // If the dialog has autoresizing enabled, |size| will be empty. Use the
+    // last known dialog size.
+    NSSize content_size = size.IsEmpty() ? current_size_ :
+        NSMakeSize(size.width(), size.height());
+    [customWindow_ setContentSize:content_size];
   }
   [super updateSheetPosition];
 }
 
+- (void)resizeWithNewSize:(NSSize)size {
+  current_size_ = size;
+  [customWindow_ setContentSize:current_size_];
+
+  // self's updateSheetPosition() sets |customWindow_|'s contentSize to a
+  // fixed dialog size. Here, we want to resize to |size| instead. Use
+  // super rather than self to bypass the setContentSize() call for the fixed
+  // size.
+  [super updateSheetPosition];
+}
+
 @end
diff --git a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
index 679c212..7c85ffe8 100644
--- a/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
+++ b/chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.mm
@@ -66,8 +66,7 @@
   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
       [[CustomConstrainedWindowSheet alloc]
           initWithCustomWindow:[sheet_controller_ window]]);
-  window_.reset(new ConstrainedWindowMac(
-      this, web_contents, sheet));
+  window_ = CreateAndShowWebModalDialogMac(this, web_contents, sheet);
 }
 
 CollectedCookiesMac::~CollectedCookiesMac() {
diff --git a/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.mm b/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.mm
index 6babaf28..881aff0 100644
--- a/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/device_permissions_dialog_controller.mm
@@ -33,8 +33,8 @@
 
   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
       [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]);
-  constrained_window_.reset(
-      new ConstrainedWindowMac(this, web_contents, sheet));
+  constrained_window_ =
+      CreateAndShowWebModalDialogMac(this, web_contents, sheet);
 }
 
 DevicePermissionsDialogController::~DevicePermissionsDialogController() {
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm
index 826a3bc..4685a25b 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm
@@ -60,8 +60,8 @@
 
   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
       [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]);
-  constrained_window_.reset(new ConstrainedWindowMac(
-      this, show_params->GetParentWebContents(), sheet));
+  constrained_window_ = CreateAndShowWebModalDialogMac(
+      this, show_params->GetParentWebContents(), sheet);
 
   std::string event_name = ExperienceSamplingEvent::kExtensionInstallDialog;
   event_name.append(
diff --git a/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.mm b/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.mm
index 01cf67c0..e3fe7a8 100644
--- a/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.mm
+++ b/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.mm
@@ -102,8 +102,8 @@
     base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
         [[CustomConstrainedWindowSheet alloc]
             initWithCustomWindow:[alert_ window]]);
-    window_.reset(new ConstrainedWindowMac(
-        this, controller->WebContents(), sheet));
+    window_ = CreateAndShowWebModalDialogMac(
+        this, controller->WebContents(), sheet);
   }
 }
 
diff --git a/chrome/browser/ui/cocoa/login_prompt_cocoa.mm b/chrome/browser/ui/cocoa/login_prompt_cocoa.mm
index 2c24253b..cd1a8443 100644
--- a/chrome/browser/ui/cocoa/login_prompt_cocoa.mm
+++ b/chrome/browser/ui/cocoa/login_prompt_cocoa.mm
@@ -80,8 +80,8 @@
     base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
         [[CustomConstrainedWindowSheet alloc]
             initWithCustomWindow:[sheet_controller_ window]]);
-    constrained_window_.reset(new ConstrainedWindowMac(
-        this, requesting_contents, sheet));
+    constrained_window_ = CreateAndShowWebModalDialogMac(
+        this, requesting_contents, sheet);
 
     NotifyAuthNeeded();
   }
diff --git a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm
index f0156f2..a8f9a84 100644
--- a/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm
+++ b/chrome/browser/ui/cocoa/one_click_signin_dialog_controller.mm
@@ -30,15 +30,15 @@
 
   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
       [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]);
-  constrained_window_.reset(new ConstrainedWindowMac(
-      this, web_contents, sheet));
+  constrained_window_ =
+      CreateAndShowWebModalDialogMac(this, web_contents, sheet);
 }
 
 OneClickSigninDialogController::~OneClickSigninDialogController() {
 }
 
 void OneClickSigninDialogController::OnConstrainedWindowClosed(
-    ConstrainedWindowMac* window) {
+  ConstrainedWindowMac* window) {
   [view_controller_ viewWillClose];
   base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
 }
diff --git a/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.mm b/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.mm
index a46b4eb..e600717 100644
--- a/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.mm
+++ b/chrome/browser/ui/cocoa/profiles/profile_signin_confirmation_dialog_cocoa.mm
@@ -59,7 +59,7 @@
   [[window contentView] addSubview:[controller_ view]];
   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
       [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window]);
-  window_.reset(new ConstrainedWindowMac(this, web_contents, sheet));
+  window_ = CreateAndShowWebModalDialogMac(this, web_contents, sheet);
 }
 
 ProfileSigninConfirmationDialogCocoa::~ProfileSigninConfirmationDialogCocoa() {
diff --git a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
index 48a02249..d7536b7 100644
--- a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
+++ b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
@@ -203,9 +203,9 @@
     base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
        [[CustomConstrainedWindowSheet alloc]
            initWithCustomWindow:[self window]]);
-    constrained_window_.reset(
-       new ConstrainedWindowMac(
-          webContentsDelegate_.get(), webContents_, sheet));
+    constrained_window_ =
+        CreateAndShowWebModalDialogMac(
+            webContentsDelegate_.get(), webContents_, sheet);
 
     // The close button needs to call CloseWebContentsModalDialog() on the
     // constrained window isntead of just [window close] so grab a reference to
diff --git a/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm b/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm
index 6b1d507..4bab882 100644
--- a/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm
+++ b/chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.mm
@@ -58,8 +58,10 @@
   [[ConstrainedWindowSheetController controllerForSheet:sheet_]
       closeSheet:sheet_];
   client_->set_manager(nullptr);
+  bool dialog_was_open = client_->DialogWasShown();
   client_->OnDialogClosing();      // |client_| might delete itself here.
-  delegate_->WillClose(dialog());  // Deletes |this|.
+  if (dialog_was_open)
+    delegate_->WillClose(dialog());  // Deletes |this|.
 }
 
 void SingleWebContentsDialogManagerCocoa::Focus() {
diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
index 8c7d66d..4a06708 100644
--- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
+++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
@@ -179,8 +179,8 @@
     CFRelease(sslPolicy);
   }
 
-  constrainedWindow_.reset(
-      new ConstrainedWindowMac(observer_.get(), webContents, self));
+  constrainedWindow_ =
+      CreateAndShowWebModalDialogMac(observer_.get(), webContents, self);
   observer_->StartObserving();
 }
 
@@ -260,6 +260,10 @@
   // NOOP
 }
 
+- (void)resizeWithNewSize:(NSSize)size {
+  // NOOP
+}
+
 - (NSWindow*)sheetWindow {
   return panel_;
 }
diff --git a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm
index 6935ce1..e0e7f547 100644
--- a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm
+++ b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm
@@ -94,7 +94,7 @@
   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
       [[CustomConstrainedWindowSheet alloc]
           initWithCustomWindow:[alert_ window]]);
-  window_.reset(new ConstrainedWindowMac(this, web_contents, sheet));
+  window_ = CreateAndShowWebModalDialogMac(this, web_contents, sheet);
   delegate_->set_close_delegate(this);
 }
 
diff --git a/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_views_mac.mm b/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_views_mac.mm
index 1eefbd15..31f057fa 100644
--- a/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_views_mac.mm
+++ b/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_views_mac.mm
@@ -96,6 +96,10 @@
   [customWindow_ setFrameOrigin:origin];
 }
 
+- (void)resizeWithNewSize:(NSSize)size {
+  // NOOP
+}
+
 - (NSWindow*)sheetWindow {
   return customWindow_;
 }
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc b/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc
index ff772c36..666d11e 100644
--- a/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc
@@ -12,21 +12,13 @@
 #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
 #include "chrome/browser/ui/exclusive_access/mouse_lock_controller.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
 using content::WebContents;
 
-const base::Feature ExclusiveAccessManager::kSimplifiedUIFeature = {
-    "ViewsSimplifiedFullscreenUI",
-#if defined(USE_AURA)
-    base::FEATURE_ENABLED_BY_DEFAULT,
-#else
-    base::FEATURE_DISABLED_BY_DEFAULT,
-#endif
-};
-
 ExclusiveAccessManager::ExclusiveAccessManager(
     ExclusiveAccessContext* exclusive_access_context)
     : exclusive_access_context_(exclusive_access_context),
@@ -100,7 +92,7 @@
 
 // static
 bool ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() {
-  return base::FeatureList::IsEnabled(kSimplifiedUIFeature);
+  return base::FeatureList::IsEnabled(features::kSimplifiedFullscreenUI);
 }
 
 void ExclusiveAccessManager::OnTabDeactivated(WebContents* web_contents) {
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_manager.h b/chrome/browser/ui/exclusive_access/exclusive_access_manager.h
index af0191fb..dae8b55 100644
--- a/chrome/browser/ui/exclusive_access/exclusive_access_manager.h
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_manager.h
@@ -27,10 +27,6 @@
 // the exit bubble to reflect the combined state.
 class ExclusiveAccessManager {
  public:
-  // A new user experience for transitioning into fullscreen and mouse pointer
-  // lock states.
-  static const base::Feature kSimplifiedUIFeature;
-
   explicit ExclusiveAccessManager(
       ExclusiveAccessContext* exclusive_access_context);
   ~ExclusiveAccessManager();
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
index 58658d8a..96691c2 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
 #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
@@ -90,14 +91,12 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     switch (GetParam()) {
       case PROMPTING:
-        command_line->AppendSwitchASCII(
-            switches::kDisableFeatures,
-            ExclusiveAccessManager::kSimplifiedUIFeature.name);
+        command_line->AppendSwitchASCII(switches::kDisableFeatures,
+                                        features::kSimplifiedFullscreenUI.name);
         break;
       case SIMPLIFIED:
-        command_line->AppendSwitchASCII(
-            switches::kEnableFeatures,
-            ExclusiveAccessManager::kSimplifiedUIFeature.name);
+        command_line->AppendSwitchASCII(switches::kEnableFeatures,
+                                        features::kSimplifiedFullscreenUI.name);
         break;
       default:
         NOTREACHED();
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
index 50ccf006..3ea39f6 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
@@ -350,14 +350,14 @@
                  ? PasswordTittleType::SAVE_PASSWORD
                  : PasswordTittleType::SAVE_ACCOUNT);
   GetSavePasswordDialogTitleTextAndLinkRange(
-      web_contents()->GetVisibleURL(), origin(),
+      web_contents()->GetVisibleURL(), origin_,
       GetSmartLockBrandingState(GetProfile()) !=
           password_bubble_experiment::SmartLockBranding::NONE,
       type, &title_, &title_brand_link_range_);
 }
 
 void ManagePasswordsBubbleModel::UpdateManageStateTitle() {
-  GetManagePasswordsDialogTitleText(web_contents()->GetVisibleURL(), origin(),
+  GetManagePasswordsDialogTitleText(web_contents()->GetVisibleURL(), origin_,
                                     &title_);
 }
 
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.h b/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
index 682a6582..d9bb324 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
@@ -73,8 +73,6 @@
   void OnPasswordAction(const autofill::PasswordForm& password_form,
                         PasswordAction action);
 
-  GURL origin() const { return origin_; }
-
   password_manager::ui::State state() const { return state_; }
 
   const base::string16& title() const { return title_; }
diff --git a/chrome/browser/ui/passwords/manage_passwords_state.cc b/chrome/browser/ui/passwords/manage_passwords_state.cc
index 436aaec2..7a22e2d0 100644
--- a/chrome/browser/ui/passwords/manage_passwords_state.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_state.cc
@@ -112,7 +112,7 @@
   current_forms_weak_ = ScopedPtrMapToVector(form_manager_->best_matches());
   AddRawPtrFromOwningVector(form_manager_->federated_matches(),
                             &current_forms_weak_);
-  origin_ = form_manager_->pending_credentials().origin;
+  origin_ = form_manager_->observed_form().origin;
   SetState(password_manager::ui::PENDING_PASSWORD_STATE);
 }
 
@@ -123,7 +123,7 @@
   current_forms_weak_ = ScopedPtrMapToVector(form_manager_->best_matches());
   AddRawPtrFromOwningVector(form_manager_->federated_matches(),
                             &current_forms_weak_);
-  origin_ = form_manager_->pending_credentials().origin;
+  origin_ = form_manager_->observed_form().origin;
   SetState(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE);
 }
 
@@ -139,11 +139,11 @@
 }
 
 void ManagePasswordsState::OnAutoSignin(
-    ScopedVector<autofill::PasswordForm> local_forms) {
+    ScopedVector<autofill::PasswordForm> local_forms, const GURL& origin) {
   DCHECK(!local_forms.empty());
   ClearData();
   local_credentials_forms_ = ConstifyVector(&local_forms);
-  origin_ = local_credentials_forms_[0]->origin;
+  origin_ = origin;
   SetState(password_manager::ui::AUTO_SIGNIN_STATE);
 }
 
@@ -160,7 +160,7 @@
   current_forms_weak_ = MapToVector(current_forms);
   AddRawPtrFromOwningVector(form_manager_->federated_matches(),
                             &current_forms_weak_);
-  origin_ = form_manager_->pending_credentials().origin;
+  origin_ = form_manager_->observed_form().origin;
   SetState(password_manager::ui::CONFIRMATION_STATE);
 }
 
diff --git a/chrome/browser/ui/passwords/manage_passwords_state.h b/chrome/browser/ui/passwords/manage_passwords_state.h
index 4053a8c..d4b902c 100644
--- a/chrome/browser/ui/passwords/manage_passwords_state.h
+++ b/chrome/browser/ui/passwords/manage_passwords_state.h
@@ -57,7 +57,8 @@
       const GURL& origin);
 
   // Move to AUTO_SIGNIN_STATE. |local_forms| can't be empty.
-  void OnAutoSignin(ScopedVector<autofill::PasswordForm> local_forms);
+  void OnAutoSignin(ScopedVector<autofill::PasswordForm> local_forms,
+                    const GURL& origin);
 
   // Move to CONFIRMATION_STATE.
   void OnAutomaticPasswordSave(
@@ -127,8 +128,8 @@
 
   void SetState(password_manager::ui::State state);
 
-  // The origin of the current page. It's used to determine which PasswordStore
-  // changes are applicable to the internal state.
+  // The origin of the current page for which the state is stored. It's used to
+  // determine which PasswordStore changes are applicable to the internal state.
   GURL origin_;
 
   // Contains the password that was submitted.
diff --git a/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc
index ae17057..8fc1a57 100644
--- a/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc
@@ -60,13 +60,17 @@
     return test_local_federated_form_;
   }
   autofill::PasswordForm& test_federated_form() { return test_federated_form_; }
+  ScopedVector<autofill::PasswordForm>& test_stored_forms() {
+    return test_stored_forms_;
+  }
   ManagePasswordsState& passwords_data() { return passwords_data_; }
 
-  // Returns a PasswordFormManager containing test_local_form() as a best match.
+  // Returns a PasswordFormManager containing |test_stored_forms_| as the best
+  // matches.
   scoped_ptr<password_manager::PasswordFormManager> CreateFormManager();
 
-  // Returns a PasswordFormManager containing test_local_form() as a best match
-  // and test_federated_form() as a stored federated credential.
+  // Returns a PasswordFormManager containing test_federated_form() as a stored
+  // federated credential.
   scoped_ptr<password_manager::PasswordFormManager>
   CreateFormManagerWithFederation();
 
@@ -97,6 +101,7 @@
   autofill::PasswordForm test_submitted_form_;
   autofill::PasswordForm test_local_federated_form_;
   autofill::PasswordForm test_federated_form_;
+  ScopedVector<autofill::PasswordForm> test_stored_forms_;
 };
 
 scoped_ptr<password_manager::PasswordFormManager>
@@ -116,16 +121,11 @@
           &password_manager_, &stub_client_, driver_.AsWeakPtr(),
           test_local_form(), false));
   test_form_manager->SimulateFetchMatchingLoginsFromPasswordStore();
-  ScopedVector<autofill::PasswordForm> stored_forms;
-  stored_forms.push_back(new autofill::PasswordForm(test_local_form()));
   if (include_federated) {
-    stored_forms.push_back(
+    test_stored_forms_.push_back(
         new autofill::PasswordForm(test_local_federated_form()));
   }
-  test_form_manager->OnGetPasswordStoreResults(std::move(stored_forms));
-  EXPECT_EQ(1u, test_form_manager->best_matches().size());
-  EXPECT_EQ(test_local_form(),
-            *test_form_manager->best_matches().begin()->second);
+  test_form_manager->OnGetPasswordStoreResults(std::move(test_stored_forms_));
   EXPECT_EQ(include_federated ? 1u : 0u,
             test_form_manager->federated_matches().size());
   if (include_federated) {
@@ -265,6 +265,7 @@
 }
 
 TEST_F(ManagePasswordsStateTest, PasswordSubmitted) {
+  test_stored_forms().push_back(new autofill::PasswordForm(test_local_form()));
   scoped_ptr<password_manager::PasswordFormManager> test_form_manager(
       CreateFormManager());
   test_form_manager->ProvisionallySave(
@@ -285,6 +286,7 @@
 }
 
 TEST_F(ManagePasswordsStateTest, PasswordSaved) {
+  test_stored_forms().push_back(new autofill::PasswordForm(test_local_form()));
   scoped_ptr<password_manager::PasswordFormManager> test_form_manager(
       CreateFormManager());
   test_form_manager->ProvisionallySave(
@@ -313,8 +315,7 @@
   passwords_data().OnPendingPassword(std::move(test_form_manager));
 
   EXPECT_THAT(passwords_data().GetCurrentForms(),
-              UnorderedElementsAre(Pointee(test_local_form()),
-                                   Pointee(test_local_federated_form())));
+              ElementsAre(Pointee(test_local_federated_form())));
   EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
 }
 
@@ -358,7 +359,8 @@
 TEST_F(ManagePasswordsStateTest, AutoSignin) {
   ScopedVector<autofill::PasswordForm> local_credentials;
   local_credentials.push_back(new autofill::PasswordForm(test_local_form()));
-  passwords_data().OnAutoSignin(std::move(local_credentials));
+  passwords_data().OnAutoSignin(std::move(local_credentials),
+                                test_local_form().origin);
   EXPECT_THAT(passwords_data().GetCurrentForms(),
               ElementsAre(Pointee(test_local_form())));
   EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
@@ -392,8 +394,7 @@
 
   passwords_data().TransitionToState(password_manager::ui::MANAGE_STATE);
   EXPECT_THAT(passwords_data().GetCurrentForms(),
-              UnorderedElementsAre(Pointee(test_local_form()),
-                                   Pointee(test_submitted_form())));
+              ElementsAre(Pointee(test_submitted_form())));
   EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
   EXPECT_EQ(password_manager::ui::MANAGE_STATE, passwords_data().state());
   EXPECT_EQ(test_submitted_form().origin, passwords_data().origin());
@@ -409,8 +410,7 @@
 
   passwords_data().OnAutomaticPasswordSave(std::move(test_form_manager));
   EXPECT_THAT(passwords_data().GetCurrentForms(),
-              UnorderedElementsAre(Pointee(test_local_form()),
-                                   Pointee(test_submitted_form()),
+              UnorderedElementsAre(Pointee(test_submitted_form()),
                                    Pointee(test_local_federated_form())));
   EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
 }
@@ -549,7 +549,8 @@
 TEST_F(ManagePasswordsStateTest, AutoSigninAddBlacklisted) {
   ScopedVector<autofill::PasswordForm> local_credentials;
   local_credentials.push_back(new autofill::PasswordForm(test_local_form()));
-  passwords_data().OnAutoSignin(std::move(local_credentials));
+  passwords_data().OnAutoSignin(std::move(local_credentials),
+                                test_local_form().origin);
   EXPECT_EQ(password_manager::ui::AUTO_SIGNIN_STATE, passwords_data().state());
 
   TestBlacklistedUpdates();
@@ -593,6 +594,7 @@
 }
 
 TEST_F(ManagePasswordsStateTest, PasswordUpdateSubmitted) {
+  test_stored_forms().push_back(new autofill::PasswordForm(test_local_form()));
   scoped_ptr<password_manager::PasswordFormManager> test_form_manager(
       CreateFormManager());
   test_form_manager->ProvisionallySave(
@@ -612,7 +614,35 @@
   TestAllUpdates();
 }
 
+TEST_F(ManagePasswordsStateTest, AndroidPasswordUpdateSubmitted) {
+  autofill::PasswordForm android_form;
+  android_form.signon_realm = "android://dHJhc2g=@com.example.android/";
+  android_form.origin = GURL(android_form.signon_realm);
+  android_form.username_value = test_submitted_form().username_value;
+  android_form.password_value = base::ASCIIToUTF16("old pass");
+  test_stored_forms().push_back(new autofill::PasswordForm(android_form));
+  scoped_ptr<password_manager::PasswordFormManager> test_form_manager(
+      CreateFormManager());
+  test_form_manager->ProvisionallySave(
+      test_submitted_form(),
+      password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
+  passwords_data().OnUpdatePassword(std::move(test_form_manager));
+
+  EXPECT_THAT(passwords_data().GetCurrentForms(),
+              ElementsAre(Pointee(android_form)));
+  EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
+  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE,
+            passwords_data().state());
+  EXPECT_EQ(test_submitted_form().origin, passwords_data().origin());
+  ASSERT_TRUE(passwords_data().form_manager());
+  android_form.password_value = test_submitted_form().password_value;
+  EXPECT_EQ(android_form,
+            passwords_data().form_manager()->pending_credentials());
+  TestAllUpdates();
+}
+
 TEST_F(ManagePasswordsStateTest, PasswordUpdateSubmittedWithFederations) {
+  test_stored_forms().push_back(new autofill::PasswordForm(test_local_form()));
   scoped_ptr<password_manager::PasswordFormManager> test_form_manager(
       CreateFormManagerWithFederation());
   test_form_manager->ProvisionallySave(
diff --git a/chrome/browser/ui/passwords/manage_passwords_test.cc b/chrome/browser/ui/passwords/manage_passwords_test.cc
index ce9efdd..ecd14c4d 100644
--- a/chrome/browser/ui/passwords/manage_passwords_test.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_test.cc
@@ -81,7 +81,9 @@
 
 void ManagePasswordsTest::SetupAutoSignin(
     ScopedVector<autofill::PasswordForm> local_credentials) {
-  GetController()->OnAutoSignin(std::move(local_credentials));
+  ASSERT_FALSE(local_credentials.empty());
+  GURL origin = local_credentials[0]->origin;
+  GetController()->OnAutoSignin(std::move(local_credentials), origin);
 }
 
 scoped_ptr<base::HistogramSamples> ManagePasswordsTest::GetSamples(
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
index 92ab0eb..dace6be 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -119,10 +119,11 @@
 }
 
 void ManagePasswordsUIController::OnAutoSignin(
-    ScopedVector<autofill::PasswordForm> local_forms) {
+    ScopedVector<autofill::PasswordForm> local_forms,
+    const GURL& origin) {
   DCHECK(!local_forms.empty());
   DestroyAccountChooser();
-  passwords_data_.OnAutoSignin(std::move(local_forms));
+  passwords_data_.OnAutoSignin(std::move(local_forms), origin);
   bubble_status_ = SHOULD_POP_UP;
   UpdateBubbleAndIconVisibility();
 }
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
index 5651cb59..ac06b69 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
@@ -54,7 +54,8 @@
       const GURL& origin,
       base::Callback<void(const password_manager::CredentialInfo&)> callback)
       override;
-  void OnAutoSignin(ScopedVector<autofill::PasswordForm> local_forms) override;
+  void OnAutoSignin(ScopedVector<autofill::PasswordForm> local_forms,
+                    const GURL& origin) override;
   void OnPromptEnableAutoSignin() override;
   void OnAutomaticPasswordSave(
       scoped_ptr<password_manager::PasswordFormManager> form_manager) override;
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
index 0c40ffc..783370d 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -605,7 +605,8 @@
 TEST_F(ManagePasswordsUIControllerTest, AutoSignin) {
   ScopedVector<autofill::PasswordForm> local_credentials;
   local_credentials.push_back(new autofill::PasswordForm(test_local_form()));
-  controller()->OnAutoSignin(std::move(local_credentials));
+  controller()->OnAutoSignin(std::move(local_credentials),
+                             test_local_form().origin);
   EXPECT_EQ(password_manager::ui::AUTO_SIGNIN_STATE, controller()->GetState());
   EXPECT_EQ(test_local_form().origin, controller()->GetOrigin());
   ASSERT_FALSE(controller()->GetCurrentForms().empty());
@@ -668,7 +669,8 @@
 TEST_F(ManagePasswordsUIControllerTest, AutofillDuringAutoSignin) {
   ScopedVector<autofill::PasswordForm> local_credentials;
   local_credentials.push_back(new autofill::PasswordForm(test_local_form()));
-  controller()->OnAutoSignin(std::move(local_credentials));
+  controller()->OnAutoSignin(std::move(local_credentials),
+                             test_local_form().origin);
   ExpectIconAndControllerStateIs(password_manager::ui::AUTO_SIGNIN_STATE);
   scoped_ptr<autofill::PasswordForm> test_form(
       new autofill::PasswordForm(test_local_form()));
diff --git a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc
index 274d7543..f70cc62c 100644
--- a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc
@@ -78,6 +78,7 @@
     PasswordTittleType dialog_type,
     base::string16* title,
     gfx::Range* title_link_range) {
+  DCHECK(!password_manager::IsValidAndroidFacetURI(form_origin_url.spec()));
   std::vector<size_t> offsets;
   std::vector<base::string16> replacements;
   int title_id = 0;
@@ -96,14 +97,7 @@
   // Check whether the registry controlled domains for user-visible URL (i.e.
   // the one seen in the omnibox) and the password form post-submit navigation
   // URL differs or not.
-  password_manager::FacetURI facet_uri =
-      password_manager::FacetURI::FromPotentiallyInvalidSpec(
-          form_origin_url.spec());
-  if (facet_uri.IsValidAndroidFacetURI()) {
-    title_id = IDS_SAVE_PASSWORD_TITLE;
-    replacements.push_back(
-        base::ASCIIToUTF16(GetHumanReadableOriginForAndroidUri(facet_uri)));
-  } else if (!SameDomainOrHost(user_visible_url, form_origin_url)) {
+  if (!SameDomainOrHost(user_visible_url, form_origin_url)) {
     title_id = IDS_SAVE_PASSWORD_TITLE;
     // TODO(palmer): Look into passing real language prefs here, not "".
     // crbug.com/498069.
@@ -130,17 +124,11 @@
 void GetManagePasswordsDialogTitleText(const GURL& user_visible_url,
                                        const GURL& password_origin_url,
                                        base::string16* title) {
+  DCHECK(!password_manager::IsValidAndroidFacetURI(password_origin_url.spec()));
   // Check whether the registry controlled domains for user-visible URL
   // (i.e. the one seen in the omnibox) and the managed password origin URL
   // differ or not.
-  password_manager::FacetURI facet_uri =
-      password_manager::FacetURI::FromPotentiallyInvalidSpec(
-          password_origin_url.spec());
-  if (facet_uri.IsValidAndroidFacetURI()) {
-    *title = l10n_util::GetStringFUTF16(
-        IDS_MANAGE_PASSWORDS_TITLE_DIFFERENT_DOMAIN,
-        base::ASCIIToUTF16(GetHumanReadableOriginForAndroidUri(facet_uri)));
-  } else if (!SameDomainOrHost(user_visible_url, password_origin_url)) {
+  if (!SameDomainOrHost(user_visible_url, password_origin_url)) {
     // TODO(palmer): Look into passing real language prefs here, not "".
     base::string16 formatted_url = url_formatter::FormatUrlForSecurityDisplay(
         password_origin_url, std::string());
diff --git a/chrome/browser/ui/passwords/manage_passwords_view_utils_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_view_utils_unittest.cc
index 946be457..15f0828 100644
--- a/chrome/browser/ui/passwords/manage_passwords_view_utils_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_view_utils_unittest.cc
@@ -80,18 +80,7 @@
      PasswordTittleType::SAVE_ACCOUNT, "this site", 0, 0},
     {"https://a.example.com/landing",
      "https://b.example.com/login#form?value=3", true,
-     PasswordTittleType::SAVE_ACCOUNT, "this site", 12, 29},
-
-     // Android update.
-     {"https://another.org", "android://m3HSJL1i83hdltRq0-o9czGb-8KJDKra4t_3JR"
-      "lnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==@com.example.android",
-      false, PasswordTittleType::SAVE_PASSWORD, "android://com.example.android",
-      0, 0},
-     {"https://another.org","android://m3HSJL1i83hdltRq0-o9czGb-8KJDKra4t_3JR"
-      "lnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==@com.example.android",
-      true, PasswordTittleType::SAVE_PASSWORD, "android://com.example.android",
-      12, 29},
-};
+     PasswordTittleType::SAVE_ACCOUNT, "this site", 12, 29}};
 
 }  // namespace
 
diff --git a/chrome/browser/ui/passwords/passwords_client_ui_delegate.h b/chrome/browser/ui/passwords/passwords_client_ui_delegate.h
index cd9d7ef..5659fd35 100644
--- a/chrome/browser/ui/passwords/passwords_client_ui_delegate.h
+++ b/chrome/browser/ui/passwords/passwords_client_ui_delegate.h
@@ -40,7 +40,8 @@
 
   // Called when the site asks user to choose from credentials. This triggers
   // the UI to prompt the user. |local_credentials| and |federated_credentials|
-  // shouldn't both be empty.
+  // shouldn't both be empty. |origin| is a URL of the site that requested a
+  // credential.
   // Returns true when the UI is shown. |callback| is called when the user made
   // a decision. If the UI isn't shown the method returns false and doesn't call
   // |callback|.
@@ -52,9 +53,10 @@
           callback) = 0;
 
   // Called when user is auto signed in to the site. |local_forms[0]| contains
-  // the credential returned to the site.
+  // the credential returned to the site. |origin| is a URL of the site.
   virtual void OnAutoSignin(
-      ScopedVector<autofill::PasswordForm> local_forms) = 0;
+      ScopedVector<autofill::PasswordForm> local_forms,
+      const GURL& origin) = 0;
 
   // Called when it's the right time to enable autosign-in explicitly.
   virtual void OnPromptEnableAutoSignin() = 0;
diff --git a/chrome/browser/ui/passwords/passwords_model_delegate.h b/chrome/browser/ui/passwords/passwords_model_delegate.h
index 123387f7..b07d718 100644
--- a/chrome/browser/ui/passwords/passwords_model_delegate.h
+++ b/chrome/browser/ui/passwords/passwords_model_delegate.h
@@ -26,7 +26,7 @@
 // and notify about user actions.
 class PasswordsModelDelegate {
  public:
-  // Returns the origin of the current page.
+  // Returns the URL of the site the current forms are retrieved for.
   virtual const GURL& GetOrigin() const = 0;
 
   // Returns the current tab state.
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
index a0302ede..c107b7b3 100644
--- a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
+++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
@@ -32,15 +32,6 @@
 // Fixed width of the bubble.
 const int kBubbleWidth = 395;
 
-// TODO(bondd): BubbleManager will eventually move this logic somewhere else,
-// and then kIsOkButtonOnLeftSide can be removed from here and
-// dialog_client_view.cc.
-#if defined(OS_WIN) || defined(OS_CHROMEOS)
-const bool kIsOkButtonOnLeftSide = true;
-#else
-const bool kIsOkButtonOnLeftSide = false;
-#endif
-
 scoped_ptr<views::StyledLabel> CreateLegalMessageLineLabel(
     const LegalMessageLine& line,
     views::StyledLabelListener* listener) {
@@ -60,11 +51,9 @@
                                          SaveCardBubbleController* controller)
     : LocationBarBubbleDelegateView(anchor_view, web_contents),
       controller_(controller),
-      save_button_(nullptr),
-      cancel_button_(nullptr),
       learn_more_link_(nullptr) {
   DCHECK(controller);
-  views::BubbleDelegateView::CreateBubble(this);
+  views::BubbleDialogDelegateView::CreateBubble(this);
 }
 
 SaveCardBubbleViews::~SaveCardBubbleViews() {}
@@ -75,7 +64,15 @@
 
 void SaveCardBubbleViews::Hide() {
   controller_ = nullptr;
-  Close();
+  CloseBubble();
+}
+
+views::View* SaveCardBubbleViews::CreateExtraView() {
+  DCHECK(!learn_more_link_);
+  learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
+  learn_more_link_->SetUnderline(false);
+  learn_more_link_->set_listener(this);
+  return learn_more_link_;
 }
 
 views::View* SaveCardBubbleViews::CreateFootnoteView() {
@@ -94,12 +91,35 @@
   return view;
 }
 
-gfx::Size SaveCardBubbleViews::GetPreferredSize() const {
-  return gfx::Size(kBubbleWidth, GetHeightForWidth(kBubbleWidth));
+bool SaveCardBubbleViews::Accept() {
+  controller_->OnSaveButton();
+  return true;
 }
 
-views::View* SaveCardBubbleViews::GetInitiallyFocusedView() {
-  return save_button_;
+bool SaveCardBubbleViews::Cancel() {
+  controller_->OnCancelButton();
+  return true;
+}
+
+int SaveCardBubbleViews::GetDialogButtons() const {
+  // This is the default for BubbleDialogDelegateView, but it's not the default
+  // for LocationBarBubbleDelegateView.
+  return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
+}
+
+base::string16 SaveCardBubbleViews::GetDialogButtonLabel(
+    ui::DialogButton button) const {
+  return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK
+                                       ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT
+                                       : IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY);
+}
+
+bool SaveCardBubbleViews::ShouldDefaultButtonBeBlue() const {
+  return true;
+}
+
+gfx::Size SaveCardBubbleViews::GetPreferredSize() const {
+  return gfx::Size(kBubbleWidth, GetHeightForWidth(kBubbleWidth));
 }
 
 base::string16 SaveCardBubbleViews::GetWindowTitle() const {
@@ -111,17 +131,6 @@
     controller_->OnBubbleClosed();
 }
 
-void SaveCardBubbleViews::ButtonPressed(views::Button* sender,
-                                        const ui::Event& event) {
-  if (sender == save_button_) {
-    controller_->OnSaveButton();
-  } else {
-    DCHECK_EQ(sender, cancel_button_);
-    controller_->OnCancelButton();
-  }
-  Close();
-}
-
 void SaveCardBubbleViews::LinkClicked(views::Link* source, int event_flags) {
   DCHECK_EQ(source, learn_more_link_);
   controller_->OnLearnMoreClicked();
@@ -188,36 +197,6 @@
     view->AddChildView(explanation_label);
   }
 
-  // Add "learn more" link and accept/cancel buttons.
-  views::View* button_view = new views::View();
-  views::BoxLayout* button_view_layout = new views::BoxLayout(
-      views::BoxLayout::kHorizontal, 0, 0, views::kRelatedButtonHSpacing);
-  button_view->SetLayoutManager(button_view_layout);
-  view->AddChildView(button_view);
-
-  learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
-  learn_more_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  learn_more_link_->SetUnderline(false);
-  learn_more_link_->set_listener(this);
-  button_view->AddChildView(learn_more_link_);
-  button_view_layout->SetFlexForView(learn_more_link_, 1);
-
-  save_button_ = new views::BlueButton(
-      this, l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT));
-  save_button_->SetIsDefault(true);
-
-  cancel_button_ = new views::LabelButton(
-      this, l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY));
-  cancel_button_->SetStyle(views::Button::STYLE_BUTTON);
-
-  if (kIsOkButtonOnLeftSide) {
-    button_view->AddChildView(save_button_);
-    button_view->AddChildView(cancel_button_);
-  } else {
-    button_view->AddChildView(cancel_button_);
-    button_view->AddChildView(save_button_);
-  }
-
   return view;
 }
 
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.h b/chrome/browser/ui/views/autofill/save_card_bubble_views.h
index 34490c49..0a9746f 100644
--- a/chrome/browser/ui/views/autofill/save_card_bubble_views.h
+++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.h
@@ -9,7 +9,6 @@
 #include "chrome/browser/ui/autofill/save_card_bubble_controller.h"
 #include "chrome/browser/ui/autofill/save_card_bubble_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h"
-#include "ui/views/controls/button/button.h"
 #include "ui/views/controls/link_listener.h"
 #include "ui/views/controls/styled_label_listener.h"
 
@@ -18,7 +17,6 @@
 }
 
 namespace views {
-class LabelButton;
 class Link;
 class StyledLabel;
 }
@@ -30,7 +28,6 @@
 // previously saved.
 class SaveCardBubbleViews : public SaveCardBubbleView,
                             public LocationBarBubbleDelegateView,
-                            public views::ButtonListener,
                             public views::LinkListener,
                             public views::StyledLabelListener {
  public:
@@ -44,20 +41,22 @@
   // SaveCardBubbleView
   void Hide() override;
 
-  // views::BubbleDelegateView
+  // views::BubbleDialogDelegateView
+  views::View* CreateExtraView() override;
   views::View* CreateFootnoteView() override;
+  bool Accept() override;
+  bool Cancel() override;
+  int GetDialogButtons() const override;
+  base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
+  bool ShouldDefaultButtonBeBlue() const override;
 
   // views::View
   gfx::Size GetPreferredSize() const override;
 
   // views::WidgetDelegate
-  views::View* GetInitiallyFocusedView() override;
   base::string16 GetWindowTitle() const override;
   void WindowClosing() override;
 
-  // views::ButtonListener
-  void ButtonPressed(views::Button* sender, const ui::Event& event) override;
-
   // views::LinkListener
   void LinkClicked(views::Link* source, int event_flags) override;
 
@@ -76,11 +75,6 @@
 
   SaveCardBubbleController* controller_;  // Weak reference.
 
-  // Button for the user to confirm saving the credit card info.
-  views::LabelButton* save_button_;
-
-  views::LabelButton* cancel_button_;
-
   views::Link* learn_more_link_;
 
   DISALLOW_COPY_AND_ASSIGN(SaveCardBubbleViews);
diff --git a/chrome/browser/ui/views/autofill/save_card_icon_view.cc b/chrome/browser/ui/views/autofill/save_card_icon_view.cc
index 0beeed6..36b3eb2 100644
--- a/chrome/browser/ui/views/autofill/save_card_icon_view.cc
+++ b/chrome/browser/ui/views/autofill/save_card_icon_view.cc
@@ -31,7 +31,7 @@
 void SaveCardIconView::OnExecuting(
     BubbleIconView::ExecuteSource execute_source) {}
 
-views::BubbleDelegateView* SaveCardIconView::GetBubble() const {
+views::BubbleDialogDelegateView* SaveCardIconView::GetBubble() const {
   SaveCardBubbleControllerImpl* controller = GetController();
   if (!controller)
     return nullptr;
diff --git a/chrome/browser/ui/views/autofill/save_card_icon_view.h b/chrome/browser/ui/views/autofill/save_card_icon_view.h
index aeed972..d2a6d03 100644
--- a/chrome/browser/ui/views/autofill/save_card_icon_view.h
+++ b/chrome/browser/ui/views/autofill/save_card_icon_view.h
@@ -27,7 +27,7 @@
  protected:
   // BubbleIconView:
   void OnExecuting(BubbleIconView::ExecuteSource execute_source) override;
-  views::BubbleDelegateView* GetBubble() const override;
+  views::BubbleDialogDelegateView* GetBubble() const override;
   gfx::VectorIconId GetVectorIcon() const override;
 
   // TabStripModelObserver:
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
index 81a488b..c9e0292c 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -85,7 +85,7 @@
     bookmark_bubble_->set_parent_window(parent_window);
   }
   views::Widget* bubble_widget =
-      views::BubbleDelegateView::CreateBubble(bookmark_bubble_);
+      views::BubbleDialogDelegateView::CreateBubble(bookmark_bubble_);
   bubble_widget->Show();
   // Select the entire title textfield contents when the bubble is first shown.
   bookmark_bubble_->title_tf_->SelectAll(true);
@@ -148,7 +148,7 @@
     apply_edits_ = false;
   }
 
-  return BubbleDelegateView::AcceleratorPressed(accelerator);
+  return LocationBarBubbleDelegateView::AcceleratorPressed(accelerator);
 }
 
 void BookmarkBubbleView::Init() {
@@ -222,6 +222,7 @@
   AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE));
   AddAccelerator(ui::Accelerator(ui::VKEY_E, ui::EF_ALT_DOWN));
   AddAccelerator(ui::Accelerator(ui::VKEY_R, ui::EF_ALT_DOWN));
+  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
 }
 
 base::string16 BookmarkBubbleView::GetWindowTitle() const {
@@ -256,7 +257,7 @@
     Profile* profile,
     const GURL& url,
     bool newly_bookmarked)
-    : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
+    : LocationBarBubbleDelegateView(anchor_view, nullptr),
       observer_(observer),
       delegate_(std::move(delegate)),
       profile_(profile),
@@ -289,7 +290,7 @@
 }
 
 void BookmarkBubbleView::GetAccessibleState(ui::AXViewState* state) {
-  BubbleDelegateView::GetAccessibleState(state);
+  LocationBarBubbleDelegateView::GetAccessibleState(state);
   state->name =
       l10n_util::GetStringUTF16(
           newly_bookmarked_ ? IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARKED :
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
index 580f4d1..4bb93aca 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
@@ -12,7 +12,7 @@
 #include "base/strings/string16.h"
 #include "chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h"
 #include "chrome/browser/ui/sync/bubble_sync_promo_delegate.h"
-#include "ui/views/bubble/bubble_delegate.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/combobox/combobox_listener.h"
 #include "url/gurl.h"
@@ -32,7 +32,7 @@
 // Bubble. BookmarkBubbleView provides views for unstarring and editing the
 // bookmark it is created with. Don't create a BookmarkBubbleView directly,
 // instead use the static Show method.
-class BookmarkBubbleView : public views::BubbleDelegateView,
+class BookmarkBubbleView : public LocationBarBubbleDelegateView,
                            public views::ButtonListener,
                            public views::ComboboxListener {
  public:
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
index ec40da0..af22884a 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
@@ -108,7 +108,14 @@
   const ui::ThemeProvider* tp = frame_->GetThemeProvider();
   int frame_image_id = active ? IDR_THEME_FRAME : IDR_THEME_FRAME_INACTIVE;
 
-  if (ui::MaterialDesignController::IsModeMaterial()) {
+  // |default_uses_color| means the default frame is painted with a solid color.
+  // When false, the default frame is painted with assets.
+#if defined(OS_CHROMEOS)
+  bool default_uses_color = true;
+#else
+  bool default_uses_color = ui::MaterialDesignController::IsModeMaterial();
+#endif
+  if (default_uses_color) {
     return ShouldPaintAsThemed() && (tp->HasCustomImage(frame_image_id) ||
                                      tp->HasCustomImage(IDR_THEME_FRAME))
                ? *tp->GetImageSkiaNamed(frame_image_id)
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 81028f96..7d583154 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -913,8 +913,8 @@
   // Update all the UI bits.
   UpdateTitleBar();
 
-  TranslateBubbleView::CloseBubble();
-  ZoomBubbleView::CloseBubble();
+  TranslateBubbleView::CloseCurrentBubble();
+  ZoomBubbleView::CloseCurrentBubble();
 }
 
 void BrowserView::ZoomChangedForActiveTab(bool can_show_bubble) {
diff --git a/chrome/browser/ui/views/infobars/confirm_infobar.cc b/chrome/browser/ui/views/infobars/confirm_infobar.cc
index 7deab92..2780bbf 100644
--- a/chrome/browser/ui/views/infobars/confirm_infobar.cc
+++ b/chrome/browser/ui/views/infobars/confirm_infobar.cc
@@ -28,10 +28,10 @@
 
 ConfirmInfoBar::ConfirmInfoBar(scoped_ptr<ConfirmInfoBarDelegate> delegate)
     : InfoBarView(std::move(delegate)),
-      label_(NULL),
-      ok_button_(NULL),
-      cancel_button_(NULL),
-      link_(NULL) {}
+      label_(nullptr),
+      ok_button_(nullptr),
+      cancel_button_(nullptr),
+      link_(nullptr) {}
 
 ConfirmInfoBar::~ConfirmInfoBar() {
   // Ensure |elevation_icon_setter_| is destroyed before |ok_button_|.
@@ -64,23 +64,18 @@
 
 void ConfirmInfoBar::ViewHierarchyChanged(
     const ViewHierarchyChangedDetails& details) {
-  if (details.is_add && details.child == this && (label_ == NULL)) {
+  if (details.is_add && details.child == this && (label_ == nullptr)) {
     ConfirmInfoBarDelegate* delegate = GetDelegate();
     label_ = CreateLabel(delegate->GetMessageText());
     AddViewToContentArea(label_);
 
     if (delegate->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) {
+      ok_button_ = CreateTextButton(
+          this, delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK));
       if (delegate->OKButtonTriggersUACPrompt()) {
-        // Use a label button even in MD mode as MD buttons don't support icons.
-        views::LabelButton* ok_button = CreateLabelButton(
-            this, delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK));
         elevation_icon_setter_.reset(new ElevationIconSetter(
-            ok_button,
+            ok_button_,
             base::Bind(&ConfirmInfoBar::Layout, base::Unretained(this))));
-        ok_button_ = ok_button;
-      } else {
-        ok_button_ = CreateTextButton(
-            this, delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK));
       }
       AddViewToContentArea(ok_button_);
       ok_button_->SizeToPreferredSize();
diff --git a/chrome/browser/ui/views/infobars/confirm_infobar.h b/chrome/browser/ui/views/infobars/confirm_infobar.h
index 0813acff3..0415488 100644
--- a/chrome/browser/ui/views/infobars/confirm_infobar.h
+++ b/chrome/browser/ui/views/infobars/confirm_infobar.h
@@ -16,6 +16,7 @@
 namespace views {
 class Button;
 class Label;
+class LabelButton;
 }
 
 // An infobar that shows a message, up to two optional buttons, and an optional,
@@ -45,7 +46,7 @@
   int NonLabelWidth() const;
 
   views::Label* label_;
-  views::Button* ok_button_;
+  views::LabelButton* ok_button_;
   views::Button* cancel_button_;
   views::Link* link_;
   scoped_ptr<ElevationIconSetter> elevation_icon_setter_;
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc
index f5cde5e..041283e5 100644
--- a/chrome/browser/ui/views/infobars/infobar_view.cc
+++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -32,6 +32,7 @@
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/button/label_button_border.h"
+#include "ui/views/controls/button/md_text_button.h"
 #include "ui/views/controls/button/menu_button.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
@@ -125,43 +126,38 @@
 }
 
 // static
-views::Button* InfoBarView::CreateTextButton(
+views::LabelButton* InfoBarView::CreateTextButton(
     views::ButtonListener* listener,
     const base::string16& text) {
-  views::LabelButton* button = CreateLabelButton(listener, text);
-  if (ui::MaterialDesignController::IsModeMaterial())
-    button->SetFontList(GetFontList());
+  views::LabelButton* button = nullptr;
+  if (ui::MaterialDesignController::IsModeMaterial()) {
+    button = views::MdTextButton::CreateStandardButton(listener, text);
+  } else {
+    button = new views::LabelButton(listener, text);
 
-  return button;
-}
+    scoped_ptr<views::LabelButtonAssetBorder> button_border(
+        new views::LabelButtonAssetBorder(views::Button::STYLE_TEXTBUTTON));
+    const int kNormalImageSet[] = IMAGE_GRID(IDR_INFOBARBUTTON_NORMAL);
+    button_border->SetPainter(
+        false, views::Button::STATE_NORMAL,
+        views::Painter::CreateImageGridPainter(kNormalImageSet));
+    const int kHoveredImageSet[] = IMAGE_GRID(IDR_INFOBARBUTTON_HOVER);
+    button_border->SetPainter(
+        false, views::Button::STATE_HOVERED,
+        views::Painter::CreateImageGridPainter(kHoveredImageSet));
+    const int kPressedImageSet[] = IMAGE_GRID(IDR_INFOBARBUTTON_PRESSED);
+    button_border->SetPainter(
+        false, views::Button::STATE_PRESSED,
+        views::Painter::CreateImageGridPainter(kPressedImageSet));
+    button->SetBorder(std::move(button_border));
+    button->set_animate_on_state_change(false);
+    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+    button->SetFontList(rb.GetFontList(ui::ResourceBundle::MediumFont));
+    button->SetFocusable(true);
+  }
 
-// static
-views::LabelButton* InfoBarView::CreateLabelButton(
-    views::ButtonListener* listener,
-    const base::string16& text) {
-  views::LabelButton* button = new views::LabelButton(listener, text);
-  scoped_ptr<views::LabelButtonAssetBorder> button_border(
-      new views::LabelButtonAssetBorder(views::Button::STYLE_TEXTBUTTON));
-  const int kNormalImageSet[] = IMAGE_GRID(IDR_INFOBARBUTTON_NORMAL);
-  button_border->SetPainter(
-      false, views::Button::STATE_NORMAL,
-      views::Painter::CreateImageGridPainter(kNormalImageSet));
-  const int kHoveredImageSet[] = IMAGE_GRID(IDR_INFOBARBUTTON_HOVER);
-  button_border->SetPainter(
-      false, views::Button::STATE_HOVERED,
-      views::Painter::CreateImageGridPainter(kHoveredImageSet));
-  const int kPressedImageSet[] = IMAGE_GRID(IDR_INFOBARBUTTON_PRESSED);
-  button_border->SetPainter(
-      false, views::Button::STATE_PRESSED,
-      views::Painter::CreateImageGridPainter(kPressedImageSet));
-
-  button->SetBorder(std::move(button_border));
-  button->set_animate_on_state_change(false);
   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));
-  button->SetFocusable(true);
   return button;
 }
 
diff --git a/chrome/browser/ui/views/infobars/infobar_view.h b/chrome/browser/ui/views/infobars/infobar_view.h
index 9486766..b1955f7 100644
--- a/chrome/browser/ui/views/infobars/infobar_view.h
+++ b/chrome/browser/ui/views/infobars/infobar_view.h
@@ -58,13 +58,8 @@
   // Creates a focusable button for use on an infobar. The appearance is
   // customized for infobars (except in Material mode).
   // NOTE: Subclasses must ignore button presses if we're unowned.
-  static views::Button* CreateTextButton(views::ButtonListener* listener,
-                                         const base::string16& text);
-
-  // Like CreateTextButton, but specifically creates a LabelButton.
-  // TODO(estade): remove this function when MD is default.
-  static views::LabelButton* CreateLabelButton(views::ButtonListener* listener,
-                                               const base::string16& text);
+  static views::LabelButton* CreateTextButton(views::ButtonListener* listener,
+                                              const base::string16& text);
 
   // Given |labels| and the total |available_width| to display them in, sets
   // each label's size so that the longest label shrinks until it reaches the
diff --git a/chrome/browser/ui/views/location_bar/bubble_icon_view.cc b/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
index 3c66ce4..24939d1 100644
--- a/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
+++ b/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
@@ -14,7 +14,7 @@
 #include "ui/native_theme/native_theme.h"
 #include "ui/views/animation/button_ink_drop_delegate.h"
 #include "ui/views/animation/ink_drop_hover.h"
-#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
 
 BubbleIconView::BubbleIconView(CommandUpdater* command_updater, int command_id)
     : image_(new views::ImageView()),
@@ -35,7 +35,7 @@
 bool BubbleIconView::IsBubbleShowing() const {
   // If the bubble is being destroyed, it's considered showing though it may be
   // already invisible currently.
-  return GetBubble() != NULL;
+  return GetBubble() != nullptr;
 }
 
 void BubbleIconView::SetImage(const gfx::ImageSkia* image_skia) {
@@ -173,7 +173,7 @@
 }
 
 void BubbleIconView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
-  views::BubbleDelegateView* bubble = GetBubble();
+  views::BubbleDialogDelegateView* bubble = GetBubble();
   if (bubble)
     bubble->OnAnchorBoundsChanged();
 }
diff --git a/chrome/browser/ui/views/location_bar/bubble_icon_view.h b/chrome/browser/ui/views/location_bar/bubble_icon_view.h
index c0941f8..d40a1e47 100644
--- a/chrome/browser/ui/views/location_bar/bubble_icon_view.h
+++ b/chrome/browser/ui/views/location_bar/bubble_icon_view.h
@@ -20,7 +20,7 @@
 }
 
 namespace views {
-class BubbleDelegateView;
+class BubbleDialogDelegateView;
 class InkDropDelegate;
 }
 
@@ -83,7 +83,7 @@
   virtual void ExecuteCommand(ExecuteSource source);
 
   // Returns the bubble instance for the icon.
-  virtual views::BubbleDelegateView* GetBubble() const = 0;
+  virtual views::BubbleDialogDelegateView* GetBubble() const = 0;
 
   // Gets the given vector icon in the correct color and size based on |active|
   // and whether Chrome's in material design mode.
diff --git a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc
index 9b3f90b..6267856 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc
@@ -15,9 +15,9 @@
 LocationBarBubbleDelegateView::LocationBarBubbleDelegateView(
     views::View* anchor_view,
     content::WebContents* web_contents)
-    : BubbleDelegateView(anchor_view,
-                         anchor_view ? views::BubbleBorder::TOP_RIGHT
-                                     : views::BubbleBorder::NONE) {
+    : BubbleDialogDelegateView(anchor_view,
+                               anchor_view ? views::BubbleBorder::TOP_RIGHT
+                                           : views::BubbleBorder::NONE) {
   // Add observer to close the bubble if the fullscreen state changes.
   if (web_contents) {
     Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
@@ -42,19 +42,21 @@
   }
 }
 
+int LocationBarBubbleDelegateView::GetDialogButtons() const {
+  return ui::DIALOG_BUTTON_NONE;
+}
+
 void LocationBarBubbleDelegateView::Observe(
     int type,
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
   DCHECK_EQ(chrome::NOTIFICATION_FULLSCREEN_CHANGED, type);
   GetWidget()->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE);
-  Close();
+  CloseBubble();
 }
 
-void LocationBarBubbleDelegateView::Close() {
-  views::Widget* widget = GetWidget();
-  if (!widget->IsClosed())
-    widget->Close();
+void LocationBarBubbleDelegateView::CloseBubble() {
+  GetWidget()->Close();
 }
 
 void LocationBarBubbleDelegateView::AdjustForFullscreen(
diff --git a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h
index 13c4f7d..c9b8fa6e 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h
@@ -8,7 +8,7 @@
 #include "base/macros.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
 
 namespace content {
 class NotificationDetails;
@@ -19,7 +19,7 @@
 // Base class for bubbles that are shown from location bar icons. The bubble
 // will automatically close when the browser transitions in or out of fullscreen
 // mode.
-class LocationBarBubbleDelegateView : public views::BubbleDelegateView,
+class LocationBarBubbleDelegateView : public views::BubbleDialogDelegateView,
                                       public content::NotificationObserver {
  public:
   enum DisplayReason {
@@ -40,6 +40,9 @@
   // Displays the bubble with appearance and behavior tailored for |reason|.
   void ShowForReason(DisplayReason reason);
 
+  // views::BubbleDialogDelegateView:
+  int GetDialogButtons() const override;
+
   // content::NotificationObserver:
   void Observe(int type,
                const content::NotificationSource& source,
@@ -47,7 +50,7 @@
 
  protected:
   // Closes the bubble.
-  virtual void Close();
+  virtual void CloseBubble();
 
   // If the bubble is not anchored to a view, places the bubble in the top right
   // (left in RTL) of the |screen_bounds| that contain web contents's browser
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 5d51bca..c488fb8 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -983,7 +983,7 @@
   const bool was_visible = zoom_view_->visible();
   zoom_view_->Update(ui_zoom::ZoomController::FromWebContents(web_contents));
   if (!zoom_view_->visible())
-    ZoomBubbleView::CloseBubble();
+    ZoomBubbleView::CloseCurrentBubble();
   return was_visible != zoom_view_->visible();
 }
 
@@ -1018,7 +1018,7 @@
   command_updater()->UpdateCommandEnabled(IDC_TRANSLATE_PAGE, enabled);
   translate_icon_view_->SetVisible(enabled);
   if (!enabled)
-    TranslateBubbleView::CloseBubble();
+    TranslateBubbleView::CloseCurrentBubble();
 }
 
 bool LocationBarView::RefreshManagePasswordsIconView() {
diff --git a/chrome/browser/ui/views/location_bar/star_view.cc b/chrome/browser/ui/views/location_bar/star_view.cc
index 38ee833b..d7ce524d 100644
--- a/chrome/browser/ui/views/location_bar/star_view.cc
+++ b/chrome/browser/ui/views/location_bar/star_view.cc
@@ -62,7 +62,7 @@
   }
 }
 
-views::BubbleDelegateView* StarView::GetBubble() const {
+views::BubbleDialogDelegateView* StarView::GetBubble() const {
   return BookmarkBubbleView::bookmark_bubble();
 }
 
diff --git a/chrome/browser/ui/views/location_bar/star_view.h b/chrome/browser/ui/views/location_bar/star_view.h
index 2bbf3c2..ec61dbdf 100644
--- a/chrome/browser/ui/views/location_bar/star_view.h
+++ b/chrome/browser/ui/views/location_bar/star_view.h
@@ -24,7 +24,7 @@
   // BubbleIconView:
   void OnExecuting(BubbleIconView::ExecuteSource execute_source) override;
   void ExecuteCommand(ExecuteSource source) override;
-  views::BubbleDelegateView* GetBubble() const override;
+  views::BubbleDialogDelegateView* GetBubble() const override;
   bool SetRasterIcon() override;
   gfx::VectorIconId GetVectorIcon() const override;
 
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
index f1aef078..fe24d20e 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -65,7 +65,7 @@
 
   // If the bubble is already showing but in a different tab, the current
   // bubble must be closed and a new one created.
-  CloseBubble();
+  CloseCurrentBubble();
 
   zoom_bubble_ = new ZoomBubbleView(anchor_view, web_contents, reason,
                                     browser_view->immersive_mode_controller());
@@ -83,7 +83,7 @@
     zoom_bubble_->set_parent_window(web_contents->GetNativeView());
 
   views::Widget* zoom_bubble_widget =
-      views::BubbleDelegateView::CreateBubble(zoom_bubble_);
+      views::BubbleDialogDelegateView::CreateBubble(zoom_bubble_);
   if (anchor_view)
     zoom_bubble_widget->AddObserver(anchor_view);
 
@@ -95,9 +95,9 @@
 }
 
 // static
-void ZoomBubbleView::CloseBubble() {
+void ZoomBubbleView::CloseCurrentBubble() {
   if (zoom_bubble_)
-    zoom_bubble_->Close();
+    zoom_bubble_->CloseBubble();
 }
 
 // static
@@ -207,12 +207,12 @@
     zoom_bubble_ = NULL;
 }
 
-void ZoomBubbleView::Close() {
+void ZoomBubbleView::CloseBubble() {
   // Widget's Close() is async, but we don't want to use zoom_bubble_ after
   // this. Additionally web_contents_ may have been destroyed.
   zoom_bubble_ = NULL;
   web_contents_ = NULL;
-  LocationBarBubbleDelegateView::Close();
+  LocationBarBubbleDelegateView::CloseBubble();
 }
 
 void ZoomBubbleView::ButtonPressed(views::Button* sender,
@@ -307,11 +307,9 @@
     // The number of milliseconds the bubble should stay on the screen if it
     // will close automatically.
     const int kBubbleCloseDelay = 1500;
-    timer_.Start(
-        FROM_HERE,
-        base::TimeDelta::FromMilliseconds(kBubbleCloseDelay),
-        this,
-        &ZoomBubbleView::Close);
+    timer_.Start(FROM_HERE,
+                 base::TimeDelta::FromMilliseconds(kBubbleCloseDelay), this,
+                 &ZoomBubbleView::CloseBubble);
   }
 }
 
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
index a40bfcca..c3b49fd 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
@@ -41,7 +41,7 @@
                          DisplayReason reason);
 
   // Closes the showing bubble (if one exists).
-  static void CloseBubble();
+  static void CloseCurrentBubble();
 
   // Returns the zoom bubble if the zoom bubble is showing. Returns NULL
   // otherwise.
@@ -81,7 +81,7 @@
   void OnMouseExited(const ui::MouseEvent& event) override;
   void Init() override;
   void WindowClosing() override;
-  void Close() override;
+  void CloseBubble() override;
 
   // views::ButtonListener:
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
index be76d0f..aa5c2817 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
@@ -103,8 +103,8 @@
   // The zoom bubble should be anchored when it is shown in immersive fullscreen
   // and the top-of-window views are revealed.
   ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC);
-  ASSERT_TRUE(ZoomBubbleView::GetZoomBubble());
   zoom_bubble = ZoomBubbleView::GetZoomBubble();
+  ASSERT_TRUE(zoom_bubble);
   EXPECT_TRUE(zoom_bubble->GetAnchorView());
 
   // The top-of-window views should not hide till the zoom bubble hides. (It
@@ -112,7 +112,7 @@
   // the zoom bubble was still visible.)
   immersive_reveal_lock.reset();
   EXPECT_TRUE(immersive_controller->IsRevealed());
-  ZoomBubbleView::CloseBubble();
+  ZoomBubbleView::CloseCurrentBubble();
   // The zoom bubble is deleted on a task.
   content::RunAllPendingInMessageLoop();
   EXPECT_FALSE(immersive_controller->IsRevealed());
diff --git a/chrome/browser/ui/views/location_bar/zoom_view.cc b/chrome/browser/ui/views/location_bar/zoom_view.cc
index fcde261..fcd4cd61 100644
--- a/chrome/browser/ui/views/location_bar/zoom_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_view.cc
@@ -29,7 +29,7 @@
   if (!zoom_controller || zoom_controller->IsAtDefaultZoom() ||
       location_bar_delegate_->GetToolbarModel()->input_in_progress()) {
     SetVisible(false);
-    ZoomBubbleView::CloseBubble();
+    ZoomBubbleView::CloseCurrentBubble();
     return;
   }
 
@@ -57,7 +57,7 @@
   state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_ZOOM);
 }
 
-views::BubbleDelegateView* ZoomView::GetBubble() const {
+views::BubbleDialogDelegateView* ZoomView::GetBubble() const {
   return ZoomBubbleView::GetZoomBubble();
 }
 
diff --git a/chrome/browser/ui/views/location_bar/zoom_view.h b/chrome/browser/ui/views/location_bar/zoom_view.h
index d37f4a6..3cff476 100644
--- a/chrome/browser/ui/views/location_bar/zoom_view.h
+++ b/chrome/browser/ui/views/location_bar/zoom_view.h
@@ -31,7 +31,7 @@
   // BubbleIconView:
   void OnExecuting(BubbleIconView::ExecuteSource source) override;
   void GetAccessibleState(ui::AXViewState* state) override;
-  views::BubbleDelegateView* GetBubble() const override;
+  views::BubbleDialogDelegateView* GetBubble() const override;
   gfx::VectorIconId GetVectorIcon() const override;
 
  private:
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
index 16527db1..a30edd4 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
@@ -264,7 +264,7 @@
 
 void ManagePasswordsBubbleView::AutoSigninView::OnTimer() {
   parent_->model()->OnAutoSignInToastTimeout();
-  parent_->Close();
+  parent_->CloseBubble();
 }
 
 // ManagePasswordsBubbleView::PendingView -------------------------------------
@@ -366,7 +366,7 @@
   else
     NOTREACHED();
 
-  parent_->Close();
+  parent_->CloseBubble();
 }
 
 void ManagePasswordsBubbleView::PendingView::StyledLabelLinkClicked(
@@ -469,14 +469,14 @@
     const ui::Event& event) {
   DCHECK(sender == done_button_);
   parent_->model()->OnDoneClicked();
-  parent_->Close();
+  parent_->CloseBubble();
 }
 
 void ManagePasswordsBubbleView::ManageView::LinkClicked(views::Link* source,
                                                         int event_flags) {
   DCHECK_EQ(source, manage_link_);
   parent_->model()->OnManageLinkClicked();
-  parent_->Close();
+  parent_->CloseBubble();
 }
 
 // ManagePasswordsBubbleView::SaveConfirmationView ----------------------------
@@ -545,14 +545,14 @@
     int event_flags) {
   DCHECK_EQ(range, parent_->model()->save_confirmation_link_range());
   parent_->model()->OnManageLinkClicked();
-  parent_->Close();
+  parent_->CloseBubble();
 }
 
 void ManagePasswordsBubbleView::SaveConfirmationView::ButtonPressed(
     views::Button* sender, const ui::Event& event) {
   DCHECK_EQ(sender, ok_button_);
   parent_->model()->OnOKClicked();
-  parent_->Close();
+  parent_->CloseBubble();
 }
 
 // ManagePasswordsBubbleView::WebContentMouseHandler --------------------------
@@ -590,19 +590,19 @@
   content::RenderViewHost* rvh = web_contents->GetRenderViewHost();
   if ((event->key_code() == ui::VKEY_ESCAPE ||
        rvh->IsFocusedElementEditable()) && event->type() == ui::ET_KEY_PRESSED)
-    bubble_->Close();
+    bubble_->CloseBubble();
 }
 
 void ManagePasswordsBubbleView::WebContentMouseHandler::OnMouseEvent(
     ui::MouseEvent* event) {
   if (event->type() == ui::ET_MOUSE_PRESSED)
-    bubble_->Close();
+    bubble_->CloseBubble();
 }
 
 void ManagePasswordsBubbleView::WebContentMouseHandler::OnTouchEvent(
     ui::TouchEvent* event) {
   if (event->type() == ui::ET_TOUCH_PRESSED)
-    bubble_->Close();
+    bubble_->CloseBubble();
 }
 
 // ManagePasswordsBubbleView::UpdatePendingView -------------------------------
@@ -699,7 +699,7 @@
   } else {
     parent_->model()->OnNopeUpdateClicked();
   }
-  parent_->Close();
+  parent_->CloseBubble();
 }
 
 void ManagePasswordsBubbleView::UpdatePendingView::StyledLabelLinkClicked(
@@ -739,7 +739,7 @@
     manage_passwords_bubble_->set_parent_window(web_contents->GetNativeView());
 
   views::Widget* manage_passwords_bubble_widget =
-      views::BubbleDelegateView::CreateBubble(manage_passwords_bubble_);
+      views::BubbleDialogDelegateView::CreateBubble(manage_passwords_bubble_);
   if (anchor_view)
     manage_passwords_bubble_widget->AddObserver(anchor_view);
 
@@ -753,9 +753,9 @@
 }
 
 // static
-void ManagePasswordsBubbleView::CloseBubble() {
+void ManagePasswordsBubbleView::CloseCurrentBubble() {
   if (manage_passwords_bubble_)
-    manage_passwords_bubble_->Close();
+    manage_passwords_bubble_->CloseBubble();
 }
 
 // static
@@ -800,9 +800,9 @@
   Refresh();
 }
 
-void ManagePasswordsBubbleView::Close() {
+void ManagePasswordsBubbleView::CloseBubble() {
   mouse_handler_.reset();
-  LocationBarBubbleDelegateView::Close();
+  LocationBarBubbleDelegateView::CloseBubble();
 }
 
 base::string16 ManagePasswordsBubbleView::GetWindowTitle() const {
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
index 8aa5e26f..22fd6a27 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
@@ -30,7 +30,7 @@
                          DisplayReason reason);
 
   // Closes the existing bubble.
-  static void CloseBubble();
+  static void CloseCurrentBubble();
 
   // Makes the bubble the foreground window.
   static void ActivateBubble();
@@ -71,7 +71,7 @@
   // LocationBarBubbleDelegateView:
   views::View* GetInitiallyFocusedView() override;
   void Init() override;
-  void Close() override;
+  void CloseBubble() override;
 
   // WidgetDelegate:
   base::string16 GetWindowTitle() const override;
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc
index 738e70c..7c9edaf 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc
@@ -86,7 +86,7 @@
       ManagePasswordsBubbleView::manage_password_bubble();
   EXPECT_TRUE(bubble->initially_focused_view());
   EXPECT_FALSE(bubble->GetFocusManager()->GetFocusedView());
-  ManagePasswordsBubbleView::CloseBubble();
+  ManagePasswordsBubbleView::CloseCurrentBubble();
   EXPECT_FALSE(IsBubbleShowing());
 
   // And, just for grins, ensure that we can re-open the bubble.
@@ -98,7 +98,7 @@
   EXPECT_TRUE(bubble->initially_focused_view());
   EXPECT_EQ(bubble->initially_focused_view(),
             bubble->GetFocusManager()->GetFocusedView());
-  ManagePasswordsBubbleView::CloseBubble();
+  ManagePasswordsBubbleView::CloseCurrentBubble();
   EXPECT_FALSE(IsBubbleShowing());
 }
 
@@ -115,13 +115,13 @@
   EXPECT_TRUE(bubble->initially_focused_view());
   EXPECT_EQ(bubble->initially_focused_view(),
             bubble->GetFocusManager()->GetFocusedView());
-  ManagePasswordsBubbleView::CloseBubble();
+  ManagePasswordsBubbleView::CloseCurrentBubble();
   EXPECT_FALSE(IsBubbleShowing());
 
   // And, just for grins, ensure that we can re-open the bubble.
   ExecuteManagePasswordsCommand();
   EXPECT_TRUE(IsBubbleShowing());
-  ManagePasswordsBubbleView::CloseBubble();
+  ManagePasswordsBubbleView::CloseCurrentBubble();
   EXPECT_FALSE(IsBubbleShowing());
 }
 
@@ -178,7 +178,7 @@
   // Open once with pending password: automagical!
   SetupPendingPassword();
   EXPECT_TRUE(IsBubbleShowing());
-  ManagePasswordsBubbleView::CloseBubble();
+  ManagePasswordsBubbleView::CloseCurrentBubble();
   // This opening should be measured as manual.
   ExecuteManagePasswordsCommand();
   EXPECT_TRUE(IsBubbleShowing());
@@ -201,7 +201,7 @@
                        CommandExecutionInAutomaticSaveState) {
   SetupAutomaticPassword();
   EXPECT_TRUE(IsBubbleShowing());
-  ManagePasswordsBubbleView::CloseBubble();
+  ManagePasswordsBubbleView::CloseCurrentBubble();
   content::RunAllPendingInMessageLoop();
   // Re-opening should count as manual.
   ExecuteManagePasswordsCommand();
@@ -320,7 +320,7 @@
   SetupAutoSignin(std::move(local_credentials));
   EXPECT_TRUE(IsBubbleShowing());
 
-  ManagePasswordsBubbleView::CloseBubble();
+  ManagePasswordsBubbleView::CloseCurrentBubble();
   EXPECT_FALSE(IsBubbleShowing());
   content::RunAllPendingInMessageLoop();
   content::WebContents* web_contents =
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
index 56e6d94..230b82d 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
@@ -27,7 +27,7 @@
   if (state_ == state)
     return;
   // If there is an opened bubble for the current icon it should go away.
-  ManagePasswordsBubbleView::CloseBubble();
+  ManagePasswordsBubbleView::CloseCurrentBubble();
   state_ = state;
   UpdateUiForState();
 }
@@ -56,7 +56,7 @@
 
 bool ManagePasswordsIconViews::OnMousePressed(const ui::MouseEvent& event) {
   bool result = BubbleIconView::OnMousePressed(event);
-  ManagePasswordsBubbleView::CloseBubble();
+  ManagePasswordsBubbleView::CloseCurrentBubble();
   return result;
 }
 
@@ -74,7 +74,7 @@
   return BubbleIconView::OnKeyPressed(event);
 }
 
-views::BubbleDelegateView* ManagePasswordsIconViews::GetBubble() const {
+views::BubbleDialogDelegateView* ManagePasswordsIconViews::GetBubble() const {
   return ManagePasswordsBubbleView::manage_password_bubble();
 }
 
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h
index 23fea160..a5b8a10 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h
@@ -29,7 +29,7 @@
   void OnExecuting(BubbleIconView::ExecuteSource source) override;
   bool OnMousePressed(const ui::MouseEvent& event) override;
   bool OnKeyPressed(const ui::KeyEvent& event) override;
-  views::BubbleDelegateView* GetBubble() const override;
+  views::BubbleDialogDelegateView* GetBubble() const override;
   gfx::VectorIconId GetVectorIcon() const override;
 
   // views::View:
diff --git a/chrome/browser/ui/views/tab_dialogs_views.cc b/chrome/browser/ui/views/tab_dialogs_views.cc
index d829ee5..ba73564 100644
--- a/chrome/browser/ui/views/tab_dialogs_views.cc
+++ b/chrome/browser/ui/views/tab_dialogs_views.cc
@@ -57,7 +57,7 @@
   if (ManagePasswordsBubbleView::manage_password_bubble()) {
     // The bubble is currently shown for some other tab. We should close it now
     // and open for |web_contents_|.
-    ManagePasswordsBubbleView::CloseBubble();
+    ManagePasswordsBubbleView::CloseCurrentBubble();
   }
   ManagePasswordsBubbleView::ShowBubble(
       web_contents_, user_action ? ManagePasswordsBubbleView::USER_GESTURE
@@ -70,7 +70,7 @@
   content::WebContents* bubble_web_contents =
       ManagePasswordsBubbleView::manage_password_bubble()->web_contents();
   if (web_contents_ == bubble_web_contents)
-    ManagePasswordsBubbleView::CloseBubble();
+    ManagePasswordsBubbleView::CloseCurrentBubble();
 }
 
 scoped_ptr<ValidationMessageBubble> TabDialogsViews::ShowValidationMessage(
diff --git a/chrome/browser/ui/views/toolbar/app_menu.cc b/chrome/browser/ui/views/toolbar/app_menu.cc
index 0920070..52143661 100644
--- a/chrome/browser/ui/views/toolbar/app_menu.cc
+++ b/chrome/browser/ui/views/toolbar/app_menu.cc
@@ -1291,7 +1291,7 @@
                                 model->bookmark_bar_node(),
                                 0,
                                 BookmarkMenuDelegate::SHOW_PERMANENT_FOLDERS,
-                                BOOKMARK_LAUNCH_LOCATION_WRENCH_MENU);
+                                BOOKMARK_LAUNCH_LOCATION_APP_MENU);
 }
 
 int AppMenu::ModelIndexFromCommandId(int command_id) const {
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc
index 0b848b83..12fa5ba5 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -120,17 +120,16 @@
       new TranslateBubbleModelImpl(step, std::move(ui_delegate)));
   TranslateBubbleView* view = new TranslateBubbleView(
       anchor_view, std::move(model), error_type, web_contents);
-  views::Widget* bubble_widget = views::BubbleDelegateView::CreateBubble(view);
+  views::Widget* bubble_widget =
+      views::BubbleDialogDelegateView::CreateBubble(view);
   view->ShowForReason(reason);
   return bubble_widget;
 }
 
 // static
-void TranslateBubbleView::CloseBubble() {
-  if (!translate_bubble_view_)
-    return;
-
-  translate_bubble_view_->GetWidget()->Close();
+void TranslateBubbleView::CloseCurrentBubble() {
+  if (translate_bubble_view_)
+    translate_bubble_view_->CloseBubble();
 }
 
 // static
@@ -213,7 +212,7 @@
       break;
     }
   }
-  return BubbleDelegateView::AcceleratorPressed(accelerator);
+  return BubbleDialogDelegateView::AcceleratorPressed(accelerator);
 }
 
 gfx::Size TranslateBubbleView::GetPreferredSize() const {
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.h b/chrome/browser/ui/views/translate/translate_bubble_view.h
index 7981edd..fbde1fd 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.h
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.h
@@ -65,8 +65,8 @@
                                    translate::TranslateErrors::Type error_type,
                                    DisplayReason reason);
 
-  // Closes the current bubble if existing.
-  static void CloseBubble();
+  // Closes the current bubble if it exists.
+  static void CloseCurrentBubble();
 
   // Returns the bubble view currently shown. This may return NULL.
   static TranslateBubbleView* GetCurrentBubble();
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc b/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc
index 9a0b9691d..329954e 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc
@@ -147,7 +147,7 @@
     bubble_ = new TranslateBubbleView(anchor_widget_->GetContentsView(),
                                       std::move(model),
                                       translate::TranslateErrors::NONE, NULL);
-    views::BubbleDelegateView::CreateBubble(bubble_)->Show();
+    views::BubbleDialogDelegateView::CreateBubble(bubble_)->Show();
   }
 
   void TearDown() override {
diff --git a/chrome/browser/ui/views/translate/translate_icon_view.cc b/chrome/browser/ui/views/translate/translate_icon_view.cc
index b406154..1b1d24c 100644
--- a/chrome/browser/ui/views/translate/translate_icon_view.cc
+++ b/chrome/browser/ui/views/translate/translate_icon_view.cc
@@ -26,7 +26,7 @@
 void TranslateIconView::OnExecuting(
     BubbleIconView::ExecuteSource execute_source) {}
 
-views::BubbleDelegateView* TranslateIconView::GetBubble() const {
+views::BubbleDialogDelegateView* TranslateIconView::GetBubble() const {
   return TranslateBubbleView::GetCurrentBubble();
 }
 
diff --git a/chrome/browser/ui/views/translate/translate_icon_view.h b/chrome/browser/ui/views/translate/translate_icon_view.h
index 764fdf2..b5c21f9 100644
--- a/chrome/browser/ui/views/translate/translate_icon_view.h
+++ b/chrome/browser/ui/views/translate/translate_icon_view.h
@@ -20,7 +20,7 @@
  protected:
   // BubbleIconView:
   void OnExecuting(BubbleIconView::ExecuteSource execute_source) override;
-  views::BubbleDelegateView* GetBubble() const override;
+  views::BubbleDialogDelegateView* GetBubble() const override;
   gfx::VectorIconId GetVectorIcon() const override;
 
  private:
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc
index fd60a4b..db4c547 100644
--- a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc
+++ b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc
@@ -113,3 +113,8 @@
   NOTREACHED();
   return gfx::Size();
 }
+
+void ConstrainedWebDialogDelegateBase::ResizeToGivenSize(
+    const gfx::Size size) {
+  NOTREACHED();
+}
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h
index fee4931..a43814a 100644
--- a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h
+++ b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h
@@ -24,6 +24,8 @@
     : public ConstrainedWebDialogDelegate,
       public ui::WebDialogWebContentsDelegate {
  public:
+  // |browser_context| and |delegate| must outlive |this| instance, whereas
+  // |this| will take ownership of |tab_delegate|.
   ConstrainedWebDialogDelegateBase(content::BrowserContext* browser_context,
                                    ui::WebDialogDelegate* delegate,
                                    WebDialogWebContentsDelegate* tab_delegate);
@@ -47,6 +49,9 @@
       content::WebContents* source,
       const content::NativeWebKeyboardEvent& event) override;
 
+  // Resize the dialog to the given size.
+  virtual void ResizeToGivenSize(const gfx::Size size);
+
  private:
   scoped_ptr<ui::WebDialogDelegate> web_dialog_delegate_;
 
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_ui.h b/chrome/browser/ui/webui/constrained_web_dialog_ui.h
index 4f7159e5..39cc74b 100644
--- a/chrome/browser/ui/webui/constrained_web_dialog_ui.h
+++ b/chrome/browser/ui/webui/constrained_web_dialog_ui.h
@@ -51,6 +51,8 @@
   // Returns the maximum size for the dialog.
   virtual gfx::Size GetMaximumSize() const = 0;
 
+  // Returns the preferred size for the dialog, or an empty size if
+  // the dialog has been closed.
   virtual gfx::Size GetPreferredSize() const = 0;
 
  protected:
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc b/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
index fbdf04f8..c3c0f361 100644
--- a/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
@@ -26,7 +26,6 @@
 
 namespace {
 
-#if !defined(OS_MACOSX)
 static const char kTestDataURL[] = "data:text/html,<!doctype html>"
     "<body></body>"
     "<style>"
@@ -42,7 +41,6 @@
   return base::StringPrintf("window.document.body.style.width = %d + 'px';"
       "window.document.body.style.height = %d + 'px';", dimension, dimension);
 }
-#endif
 
 class ConstrainedWebDialogBrowserTestObserver
     : public content::WebContentsObserver {
@@ -147,7 +145,6 @@
   EXPECT_TRUE(observer.contents_destroyed());
 }
 
-#if !defined(OS_MACOSX)
 // Tests that dialog autoresizes based on web contents when autoresizing
 // is enabled.
 IN_PROC_BROWSER_TEST_F(ConstrainedWebDialogBrowserTest,
@@ -173,6 +170,13 @@
   gfx::Size min_size = gfx::Size(100, 100);
   gfx::Size max_size = gfx::Size(200, 200);
   gfx::Size initial_dialog_size;
+
+ // OSX windows must be initially created with non-empty dimensions. The
+ // autoresizeable dialog's window dimensions are determined after initial
+ // creation.
+#if defined(OS_MACOSX)
+  initial_dialog_size = gfx::Size(1, 1);
+#endif
   delegate->GetDialogSize(&initial_dialog_size);
 
   ConstrainedWebDialogDelegate* dialog_delegate =
@@ -186,7 +190,6 @@
   EXPECT_EQ(max_size, dialog_delegate->GetMaximumSize());
 
   // Check for initial sizing. Dialog was created as a 400x400 dialog.
-  EXPECT_EQ(gfx::Size(), web_contents->GetPreferredSize());
   ASSERT_EQ(initial_dialog_size, dialog_delegate->GetPreferredSize());
 
   observer.Wait();
@@ -250,7 +253,6 @@
   delegate->GetDialogSize(&initial_dialog_size);
 
   // Check for initial sizing. Dialog was created as a 400x400 dialog.
-  EXPECT_EQ(gfx::Size(), web_contents->GetPreferredSize());
   ASSERT_EQ(initial_dialog_size, dialog_delegate->GetPreferredSize());
 
   // Resize <body> to dimension smaller than dialog.
@@ -269,4 +271,3 @@
       initial_dialog_size,
       dialog_delegate)));
 }
-#endif  // !OS_MACOSX
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
index a76bdac..35a23d4c 100644
--- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
@@ -52,6 +52,7 @@
 const char kReportInitialAction[] = "reportInitialAction";
 const char kReportInitialState[] = "reportInitialState";
 const char kReportNavigateToView[] = "reportNavigateToView";
+const char kReportRouteCreationOutcome[] = "reportRouteCreationOutcome";
 const char kReportRouteCreation[] = "reportRouteCreation";
 const char kReportSelectedCastMode[] = "reportSelectedCastMode";
 const char kReportSinkCount[] = "reportSinkCount";
@@ -346,6 +347,10 @@
       base::Bind(&MediaRouterWebUIMessageHandler::OnReportRouteCreation,
                  base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
+      kReportRouteCreationOutcome,
+      base::Bind(&MediaRouterWebUIMessageHandler::OnReportRouteCreationOutcome,
+                 base::Unretained(this)));
+  web_ui()->RegisterMessageCallback(
       kReportSelectedCastMode,
       base::Bind(&MediaRouterWebUIMessageHandler::OnReportSelectedCastMode,
                  base::Unretained(this)));
@@ -654,6 +659,19 @@
                         route_created_successfully);
 }
 
+void MediaRouterWebUIMessageHandler::OnReportRouteCreationOutcome(
+    const base::ListValue* args) {
+  DVLOG(1) << "OnReportRouteCreationOutcome";
+  int outcome;
+  if (!args->GetInteger(0, &outcome)) {
+    DVLOG(1) << "Unable to extract args.";
+    return;
+  }
+
+  media_router::MediaRouterMetrics::RecordRouteCreationOutcome(
+      static_cast<MediaRouterRouteCreationOutcome>(outcome));
+}
+
 void MediaRouterWebUIMessageHandler::OnReportSelectedCastMode(
     const base::ListValue* args) {
   DVLOG(1) << "OnReportSelectedCastMode";
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h
index 20c84ed6..81dc3c3 100644
--- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h
+++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h
@@ -74,6 +74,7 @@
   void OnReportInitialState(const base::ListValue* args);
   void OnReportNavigateToView(const base::ListValue* args);
   void OnReportRouteCreation(const base::ListValue* args);
+  void OnReportRouteCreationOutcome(const base::ListValue* args);
   void OnReportSelectedCastMode(const base::ListValue* args);
   void OnReportSinkCount(const base::ListValue* args);
   void OnReportTimeToClickSink(const base::ListValue* args);
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 2954929..9b7080ba 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2867,6 +2867,8 @@
       'browser/ssl/chrome_ssl_host_state_delegate_factory.h',
       'browser/ssl/common_name_mismatch_handler.cc',
       'browser/ssl/common_name_mismatch_handler.h',
+      'browser/ssl/chrome_expect_ct_reporter.cc',
+      'browser/ssl/chrome_expect_ct_reporter.h',
       'browser/ssl/ssl_blocking_page.cc',
       'browser/ssl/ssl_blocking_page.h',
       'browser/ssl/ssl_cert_reporter.h',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index f715dfc..e66e88a 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -2123,6 +2123,8 @@
       'browser/ui/views/extensions/extension_keybinding_registry_views.h',
       'browser/ui/views/frame/native_widget_mac_frameless_nswindow.h',
       'browser/ui/views/frame/native_widget_mac_frameless_nswindow.mm',
+      'browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc',
+      'browser/ui/views/location_bar/location_bar_bubble_delegate_view.h',
       'browser/ui/views/login_prompt_views.cc',
       'browser/ui/views/login_view.cc',
       'browser/ui/views/login_view.h',
@@ -2352,8 +2354,6 @@
       'browser/ui/views/location_bar/icon_label_bubble_view.h',
       'browser/ui/views/location_bar/keyword_hint_view.cc',
       'browser/ui/views/location_bar/keyword_hint_view.h',
-      'browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc',
-      'browser/ui/views/location_bar/location_bar_bubble_delegate_view.h',
       'browser/ui/views/location_bar/location_bar_decoration_view.cc',
       'browser/ui/views/location_bar/location_bar_decoration_view.h',
       'browser/ui/views/location_bar/location_bar_layout.cc',
diff --git a/chrome/chrome_watcher/chrome_watcher_main.cc b/chrome/chrome_watcher/chrome_watcher_main.cc
index 18f4b5a..1976c7a 100644
--- a/chrome/chrome_watcher/chrome_watcher_main.cc
+++ b/chrome/chrome_watcher/chrome_watcher_main.cc
@@ -27,7 +27,6 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
-#include "base/template_util.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/threading/thread.h"
 #include "base/time/time.h"
@@ -443,5 +442,5 @@
 }
 
 static_assert(
-    base::is_same<decltype(&WatcherMain), ChromeWatcherMainFunction>::value,
+    std::is_same<decltype(&WatcherMain), ChromeWatcherMainFunction>::value,
     "WatcherMain() has wrong type");
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 418e283..a3787180 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -29,4 +29,18 @@
     "RuntimeMemoryLeakDetector", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif  // defined(OS_CHROMEOS)
 
+// A new user experience for transitioning into fullscreen and mouse pointer
+// lock states. The name is a misnomer (for historical reasons); affects both
+// Views and Android builds.
+const base::Feature kSimplifiedFullscreenUI{
+    "ViewsSimplifiedFullscreenUI",
+#if defined(USE_AURA)
+    // Windows, Linux, Chrome OS.
+    base::FEATURE_ENABLED_BY_DEFAULT,
+#else
+    // Mac, Android.
+    base::FEATURE_DISABLED_BY_DEFAULT,
+#endif
+};
+
 }  // namespace features
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index e881669..62f7992 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -23,10 +23,13 @@
 extern const base::Feature kLinuxObsoleteSystemIsEndOfTheLine;
 #endif
 
+
 #if defined(OS_CHROMEOS)
 extern const base::Feature kRuntimeMemoryLeakDetector;
 #endif  // defined(OS_CHROMEOS)
 
+extern const base::Feature kSimplifiedFullscreenUI;
+
 // DON'T ADD RANDOM STUFF HERE. Put it in the main section above in
 // alphabetical order, or in one of the ifdefs (also in order in each section).
 
diff --git a/chrome/common/extensions/chrome_extension_messages.h b/chrome/common/extensions/chrome_extension_messages.h
index 49357df..80c565f 100644
--- a/chrome/common/extensions/chrome_extension_messages.h
+++ b/chrome/common/extensions/chrome_extension_messages.h
@@ -74,6 +74,7 @@
 IPC_STRUCT_TRAITS_BEGIN(ui::AXTreeData)
   IPC_STRUCT_TRAITS_MEMBER(tree_id)
   IPC_STRUCT_TRAITS_MEMBER(parent_tree_id)
+  IPC_STRUCT_TRAITS_MEMBER(focused_tree_id)
   IPC_STRUCT_TRAITS_MEMBER(url)
   IPC_STRUCT_TRAITS_MEMBER(title)
   IPC_STRUCT_TRAITS_MEMBER(mimetype)
diff --git a/chrome/common/mac/mock_launchd.cc b/chrome/common/mac/mock_launchd.cc
index 30fd383..2453335 100644
--- a/chrome/common/mac/mock_launchd.cc
+++ b/chrome/common/mac/mock_launchd.cc
@@ -24,10 +24,6 @@
 #include "components/version_info/version_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-static sockaddr_un* throwaway_sockaddr_un;
-static const size_t kMaxPipeNameLength =
-    sizeof(throwaway_sockaddr_un->sun_path);
-
 // static
 bool MockLaunchd::MakeABundle(const base::FilePath& dst,
                               const std::string& name,
@@ -168,8 +164,8 @@
   // Create unix_addr structure.
   struct sockaddr_un unix_addr = {0};
   unix_addr.sun_family = AF_UNIX;
-  size_t path_len =
-      base::strlcpy(unix_addr.sun_path, pipe_name_.c_str(), kMaxPipeNameLength);
+  size_t path_len = base::strlcpy(unix_addr.sun_path, pipe_name_.c_str(),
+                                  sizeof(unix_addr.sun_path));
   DCHECK_EQ(pipe_name_.length(), path_len);
   unix_addr.sun_len = SUN_LEN(&unix_addr);
 
diff --git a/chrome/ct_top1k.isolate b/chrome/ct_top1k.isolate
index 14be85fa..3d0d97e 100644
--- a/chrome/ct_top1k.isolate
+++ b/chrome/ct_top1k.isolate
@@ -14,7 +14,6 @@
       'variables': {
         'files': [
           '../build/android/pylib/',
-          '../build/android/devil/',
           '../testing/variations/',
           '../third_party/catapult/',
           '../tools/perf/',
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc
index a8660d36..29c0df7d 100644
--- a/chrome/installer/setup/install.cc
+++ b/chrome/installer/setup/install.cc
@@ -10,6 +10,7 @@
 
 #include <string>
 
+#include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -37,6 +38,7 @@
 #include "chrome/installer/util/master_preferences.h"
 #include "chrome/installer/util/master_preferences_constants.h"
 #include "chrome/installer/util/set_reg_value_work_item.h"
+#include "chrome/installer/util/shell_util.h"
 #include "chrome/installer/util/util_constants.h"
 #include "chrome/installer/util/work_item.h"
 #include "chrome/installer/util/work_item_list.h"
@@ -251,6 +253,49 @@
   return installer::INSTALL_FAILED;
 }
 
+void UpdatePerUserShortcutsInLocation(
+    const ShellUtil::ShortcutLocation shortcut_location,
+    BrowserDistribution* dist,
+    const base::FilePath& old_target_path_prefix,
+    const base::FilePath& old_target_path_suffix,
+    const base::FilePath& new_target_path) {
+  base::FilePath shortcut_path;
+  const bool get_shortcut_path_return = ShellUtil::GetShortcutPath(
+      shortcut_location, dist, ShellUtil::CURRENT_USER, &shortcut_path);
+  DCHECK(get_shortcut_path_return);
+
+  bool recursive = false;
+
+  // TODO(fdoray): Modify GetShortcutPath such that it returns
+  // ...\Quick Launch\User Pinned instead of
+  // ...\Quick Launch\User Pinned\TaskBar for SHORTCUT_LOCATION_TASKBAR_PINS.
+  if (shortcut_location == ShellUtil::SHORTCUT_LOCATION_TASKBAR_PINS) {
+    shortcut_path = shortcut_path.DirName();
+    recursive = true;
+  }
+
+  base::FileEnumerator shortcuts_enum(shortcut_path, recursive,
+                                      base::FileEnumerator::FILES);
+  for (base::FilePath shortcut = shortcuts_enum.Next(); !shortcut.empty();
+       shortcut = shortcuts_enum.Next()) {
+    base::FilePath existing_target_path;
+    if (!base::win::ResolveShortcut(shortcut, &existing_target_path, nullptr) ||
+        !base::StartsWith(existing_target_path.value(),
+                          old_target_path_prefix.value(),
+                          base::CompareCase::INSENSITIVE_ASCII) ||
+        !base::EndsWith(existing_target_path.value(),
+                        old_target_path_suffix.value(),
+                        base::CompareCase::INSENSITIVE_ASCII)) {
+      continue;
+    }
+
+    base::win::ShortcutProperties updated_properties;
+    updated_properties.set_target(new_target_path);
+    base::win::CreateOrUpdateShortcutLink(shortcut, updated_properties,
+                                          base::win::SHORTCUT_UPDATE_EXISTING);
+  }
+}
+
 }  // end namespace
 
 namespace installer {
@@ -418,6 +463,21 @@
   ExecuteAndLogShortcutOperation(
       ShellUtil::SHORTCUT_LOCATION_START_MENU_ROOT, dist,
       start_menu_properties, shortcut_operation);
+
+  // Update the target path of existing per-user shortcuts.
+  if (install_operation == INSTALL_SHORTCUT_REPLACE_EXISTING) {
+    const base::FilePath updated_prefix = target.DirName().DirName();
+    const base::FilePath updated_suffix = target.BaseName();
+
+    UpdatePerUserShortcutsInLocation(ShellUtil::SHORTCUT_LOCATION_DESKTOP, dist,
+                                     updated_prefix, updated_suffix, target);
+    UpdatePerUserShortcutsInLocation(ShellUtil::SHORTCUT_LOCATION_QUICK_LAUNCH,
+                                     dist, updated_prefix, updated_suffix,
+                                     target);
+    UpdatePerUserShortcutsInLocation(ShellUtil::SHORTCUT_LOCATION_TASKBAR_PINS,
+                                     dist, updated_prefix, updated_suffix,
+                                     target);
+  }
 }
 
 void RegisterChromeOnMachine(const installer::InstallerState& installer_state,
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.cc b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
index 44bfb90..8f1d31e6a 100644
--- a/chrome/renderer/extensions/automation_internal_custom_bindings.cc
+++ b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
@@ -136,12 +136,26 @@
       }
       need_to_offset_web_area = true;
     }
-    parent = parent->parent();
+    parent = cache->owner->GetParent(parent, &cache);
   }
 
   return bounds;
 }
 
+ui::AXNode* FindNodeWithChildTreeId(ui::AXNode* node, int child_tree_id) {
+  if (child_tree_id == node->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID))
+    return node;
+
+  for (int i = 0; i < node->child_count(); ++i) {
+    ui::AXNode* result =
+        FindNodeWithChildTreeId(node->ChildAtIndex(i), child_tree_id);
+    if (result)
+      return result;
+  }
+
+  return nullptr;
+}
+
 //
 // Helper class that helps implement bindings for a JavaScript function
 // that takes a single input argument consisting of a Tree ID. Looks up
@@ -771,6 +785,8 @@
   if (!focus)
     return false;
 
+  // If the focused node is the owner of a child tree, that indicates
+  // a node within the child tree is the one that actually has focus.
   while (focus->data().HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
     // Try to keep following focus recursively, by letting |tree_id| be the
     // new subtree to search in, while keeping |focus_tree_id| set to the tree
@@ -782,6 +798,15 @@
     if (!child_cache)
       break;
 
+    // If the child cache is a frame tree that indicates a focused frame,
+    // jump to that frame if possible.
+    if (child_cache->tree.data().focused_tree_id > 0) {
+      TreeCache* focused_cache =
+          GetTreeCacheFromTreeID(child_cache->tree.data().focused_tree_id);
+      if (focused_cache)
+        child_cache = focused_cache;
+    }
+
     int child_focus_id = child_cache->tree.data().focus_id;
     ui::AXNode* child_focus = child_cache->tree.GetFromId(child_focus_id);
     if (!child_focus)
@@ -878,6 +903,47 @@
   }
 }
 
+ui::AXNode* AutomationInternalCustomBindings::GetParent(
+    ui::AXNode* node,
+    TreeCache** in_out_cache) {
+  if (node->parent())
+    return node->parent();
+
+  int parent_tree_id = (*in_out_cache)->tree.data().parent_tree_id;
+  if (parent_tree_id < 0)
+    return nullptr;
+
+  TreeCache* parent_cache = GetTreeCacheFromTreeID(parent_tree_id);
+  if (!parent_cache)
+    return nullptr;
+
+  // Try to use the cached parent node from the most recent time this
+  // was called.
+  if (parent_cache->parent_node_id_from_parent_tree > 0) {
+    ui::AXNode* parent = parent_cache->tree.GetFromId(
+        parent_cache->parent_node_id_from_parent_tree);
+    if (parent) {
+      int parent_child_tree_id =
+          parent->data().GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID);
+      if (parent_child_tree_id == (*in_out_cache)->tree_id) {
+        *in_out_cache = parent_cache;
+        return parent;
+      }
+    }
+  }
+
+  // If that fails, search for it and cache it for next time.
+  ui::AXNode* parent = FindNodeWithChildTreeId(parent_cache->tree.root(),
+                                               (*in_out_cache)->tree_id);
+  if (parent) {
+    (*in_out_cache)->parent_node_id_from_parent_tree = parent->id();
+    *in_out_cache = parent_cache;
+    return parent;
+  }
+
+  return nullptr;
+}
+
 void AutomationInternalCustomBindings::RouteTreeIDFunction(
     const std::string& name,
     TreeIDFunction callback) {
@@ -953,7 +1019,9 @@
     cache = new TreeCache();
     cache->tab_id = -1;
     cache->tree_id = params.tree_id;
+    cache->parent_node_id_from_parent_tree = -1;
     cache->tree.SetDelegate(this);
+    cache->owner = this;
     tree_id_to_tree_cache_map_.insert(std::make_pair(tree_id, cache));
     axtree_to_tree_cache_map_.insert(std::make_pair(&cache->tree, cache));
   } else {
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.h b/chrome/renderer/extensions/automation_internal_custom_bindings.h
index d4228e7..bcca2ed 100644
--- a/chrome/renderer/extensions/automation_internal_custom_bindings.h
+++ b/chrome/renderer/extensions/automation_internal_custom_bindings.h
@@ -17,6 +17,7 @@
 
 namespace extensions {
 
+class AutomationInternalCustomBindings;
 class AutomationMessageFilter;
 
 struct TreeCache {
@@ -25,9 +26,11 @@
 
   int tab_id;
   int tree_id;
+  int parent_node_id_from_parent_tree;
 
   gfx::Vector2d location_offset;
   ui::AXTree tree;
+  AutomationInternalCustomBindings* owner;
 };
 
 struct TreeChangeObserver {
@@ -48,6 +51,8 @@
 
   TreeCache* GetTreeCacheFromTreeID(int tree_id);
 
+  ui::AXNode* GetParent(ui::AXNode* node, TreeCache** in_out_cache);
+
   ScriptContext* context() const {
     return ObjectBackedNativeHandler::context();
   }
diff --git a/chrome/renderer/page_load_histograms.cc b/chrome/renderer/page_load_histograms.cc
index f460439..56d2cee 100644
--- a/chrome/renderer/page_load_histograms.cc
+++ b/chrome/renderer/page_load_histograms.cc
@@ -8,7 +8,6 @@
 
 #include <string>
 
-#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/metrics/field_trial.h"
@@ -853,51 +852,39 @@
 }  // namespace
 
 PageLoadHistograms::PageLoadHistograms(content::RenderView* render_view)
-    : content::RenderViewObserver(render_view),
-      dumped_first_layout_histograms_(false),
-      weak_factory_(this) {
+    : content::RenderViewObserver(render_view) {
 }
 
 PageLoadHistograms::~PageLoadHistograms() {
 }
 
-bool PageLoadHistograms::ShouldDump(WebFrame* frame) {
+void PageLoadHistograms::Dump(WebFrame* frame) {
   // We only dump histograms for main frames.
   // In the future, it may be interesting to tag subframes and dump them too.
   if (!frame || frame->parent())
-    return false;
+    return;
 
   // If the main frame lives in a different process, don't do anything.
   // Histogram data will be recorded by the real main frame.
   if (frame->isWebRemoteFrame())
-    return false;
+    return;
 
   // Only dump for supported schemes.
   URLPattern::SchemeMasks scheme_type =
       GetSupportedSchemeType(frame->document().url());
   if (scheme_type == 0)
-    return false;
+    return;
 
   // Don't dump stats for the NTP, as PageLoadHistograms should only be recorded
   // for pages visited due to an explicit user navigation.
   if (SearchBouncer::GetInstance()->IsNewTabPage(frame->document().url())) {
-    return false;
+    return;
   }
 
   // Ignore multipart requests.
   if (frame->dataSource()->response().isMultipartPayload())
-    return false;
-
-  return true;
-}
-
-void PageLoadHistograms::Dump(WebFrame* frame) {
-  if (!ShouldDump(frame))
     return;
 
-  URLPattern::SchemeMasks scheme_type =
-      GetSupportedSchemeType(frame->document().url());
-
   DocumentState* document_state =
       DocumentState::FromDataSource(frame->dataSource());
 
@@ -922,8 +909,6 @@
     is_preview = ViaHeaderContains(frame, "1.1 Google Instant Proxy Preview");
   }
 
-  MaybeDumpFirstLayoutHistograms();
-
   content::RenderFrame* render_frame =
       content::RenderFrame::FromWebFrame(frame);
 
@@ -958,29 +943,6 @@
       content::kHistogramSynchronizerReservedSequenceNumber);
 }
 
-void PageLoadHistograms::MaybeDumpFirstLayoutHistograms() {
-  if (dumped_first_layout_histograms_)
-    return;
-
-  const WebPerformance& performance =
-    render_view()->GetWebView()->mainFrame()->performance();
-  Time first_layout = Time::FromDoubleT(performance.firstLayout());
-  if (first_layout.is_null())
-    return;
-
-  Time navigation_start = Time::FromDoubleT(performance.navigationStart());
-  if (!navigation_start.is_null())
-    PLT_HISTOGRAM("PLT.PT.NavigationStartToFirstLayout",
-                  first_layout - navigation_start);
-
-  Time response_start = Time::FromDoubleT(performance.responseStart());
-  if (!response_start.is_null())
-    PLT_HISTOGRAM("PLT.PT.ResponseStartToFirstLayout",
-                  first_layout - response_start);
-
-  dumped_first_layout_histograms_ = true;
-}
-
 void PageLoadHistograms::FrameWillClose(WebFrame* frame) {
   Dump(frame);
 }
@@ -992,49 +954,6 @@
   Dump(render_view()->GetWebView()->mainFrame());
 }
 
-void PageLoadHistograms::DidUpdateLayout() {
-  DCHECK(content::RenderThread::Get());
-  // Normally, PageLoadHistograms dumps all histograms in the FrameWillClose or
-  // ClosePage callbacks, which happen as a page is being torn down. However,
-  // renderers that are killed by fast shutdown (for example, renderers closed
-  // due to the user closing a tab) don't get a chance to run these callbacks
-  // (see crbug.com/382542 for details).
-  //
-  // Longer term, we need to migrate histogram recording to happen earlier in
-  // the page load life cycle, so histograms aren't lost when tabs are
-  // closed. As a first step, we use the RenderViewObserver::DidUpdateLayout
-  // callback to log first layout histograms earlier in the page load life
-  // cycle.
-
-  if (dumped_first_layout_histograms_)
-    return;
-
-  WebFrame* frame = render_view()->GetWebView()->mainFrame();
-  if (!ShouldDump(frame))
-    return;
-
-  // The canonical source for the 'first layout time' is the
-  // blink::WebPerformance object, so we need to read the first layout timestamp
-  // from that object, rather than taking our own timestamp in this
-  // callback.
-  //
-  // This DidUpdateLayout callback gets invoked in the midst of the
-  // layout process. The logic that records the first layout time in the
-  // blink::WebPerformance object may run later in the layout process, after
-  // DidUpdateLayout gets invoked. Thus, we schedule a callback to run
-  // MaybeDumpFirstLayoutHistograms asynchronously, after the layout process is
-  // complete.
-  //
-  // Note, too, that some layouts are performed with pending stylesheets, and
-  // blink will not record firstLayout during those layouts, so firstLayout may
-  // not be populated during the layout associated with the first
-  // DidUpdateLayout callback.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(&PageLoadHistograms::MaybeDumpFirstLayoutHistograms,
-                 weak_factory_.GetWeakPtr()));
-}
-
 void PageLoadHistograms::LogPageLoadTime(const DocumentState* document_state,
                                          const WebDataSource* ds) const {
   // Because this function gets called on every page load,
diff --git a/chrome/renderer/page_load_histograms.h b/chrome/renderer/page_load_histograms.h
index 4778a8a0..36996559 100644
--- a/chrome/renderer/page_load_histograms.h
+++ b/chrome/renderer/page_load_histograms.h
@@ -6,7 +6,6 @@
 #define CHROME_RENDERER_PAGE_LOAD_HISTOGRAMS_H_
 
 #include "base/macros.h"
-#include "base/memory/weak_ptr.h"
 #include "content/public/renderer/render_view_observer.h"
 
 namespace blink {
@@ -26,7 +25,6 @@
   // RenderViewObserver implementation.
   void FrameWillClose(blink::WebFrame* frame) override;
   void ClosePage() override;
-  void DidUpdateLayout() override;
 
   // Dump all page load histograms appropriate for the given frame.
   //
@@ -49,14 +47,9 @@
   // so first_paint and first_paint_after_load can be 0.
   void Dump(blink::WebFrame* frame);
 
-  bool ShouldDump(blink::WebFrame* frame);
-  void MaybeDumpFirstLayoutHistograms();
   void LogPageLoadTime(const content::DocumentState* load_times,
                        const blink::WebDataSource* ds) const;
 
-  bool dumped_first_layout_histograms_;
-  base::WeakPtrFactory<PageLoadHistograms> weak_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(PageLoadHistograms);
 };
 
diff --git a/chrome/test/base/v8_unit_test.cc b/chrome/test/base/v8_unit_test.cc
index 392ff45b..9f52f06 100644
--- a/chrome/test/base/v8_unit_test.cc
+++ b/chrome/test/base/v8_unit_test.cc
@@ -11,7 +11,6 @@
 #include "base/strings/stringprintf.h"
 #include "chrome/common/chrome_paths.h"
 #include "third_party/WebKit/public/web/WebKit.h"
-#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 
 namespace {
 
@@ -96,7 +95,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   v8::Local<v8::Value> function_property =
       context->Global()->Get(v8::String::NewFromUtf8(isolate, "runTest"));
@@ -211,7 +209,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
   v8::Local<v8::String> source =
       v8::String::NewFromUtf8(isolate,
                               script_source.data(),
@@ -260,7 +257,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   v8::Local<v8::Value> function_property = context->Global()->Get(
       v8::String::NewFromUtf8(isolate, function_name.c_str()));
diff --git a/chrome/test/data/extensions/api_test/automation/sites/iframe_inner.html b/chrome/test/data/extensions/api_test/automation/sites/iframe_inner.html
new file mode 100644
index 0000000..0ce5da6
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/automation/sites/iframe_inner.html
@@ -0,0 +1,3 @@
+<body>
+  <div><button>Inner</button></div>
+</body>
diff --git a/chrome/test/data/extensions/api_test/automation/sites/iframe_outer.html b/chrome/test/data/extensions/api_test/automation/sites/iframe_outer.html
new file mode 100644
index 0000000..bf9426f
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/automation/sites/iframe_outer.html
@@ -0,0 +1,3 @@
+<body>
+  <iframe src="iframe_inner.html"></iframe>
+</body>
diff --git a/chrome/test/data/extensions/api_test/automation/tests/desktop/focus_iframe.html b/chrome/test/data/extensions/api_test/automation/tests/desktop/focus_iframe.html
new file mode 100644
index 0000000..e43e1ccf
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/automation/tests/desktop/focus_iframe.html
@@ -0,0 +1,7 @@
+<!--
+ * Copyright 2016 The Chromium Authors. All rights reserved.  Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+-->
+<script src="common.js"></script>
+<script src="focus_iframe.js"></script>
diff --git a/chrome/test/data/extensions/api_test/automation/tests/desktop/focus_iframe.js b/chrome/test/data/extensions/api_test/automation/tests/desktop/focus_iframe.js
new file mode 100644
index 0000000..ee69b37
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/automation/tests/desktop/focus_iframe.js
@@ -0,0 +1,37 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var allTests = [
+  function testFocusInIframes() {
+    chrome.test.getConfig(function(config) {
+      var url = 'http://a.com:' + config.testServer.port + '/iframe_outer.html';
+      chrome.tabs.create({url: url});
+
+      chrome.automation.getDesktop(function(rootNode) {
+        // Succeed when the button inside the iframe gets focus.
+        rootNode.addEventListener('focus', function(event) {
+          if (event.target.name == 'Inner')
+            chrome.test.succeed();
+        });
+
+        // Wait for the inner frame to load, then find the button inside it
+        // and focus it.
+        rootNode.addEventListener('loadComplete', function(event) {
+          if (event.target.url.indexOf('iframe_inner.html') >= 0) {
+            chrome.automation.getFocus(function(focus) {
+              // Assert that the outer frame has focus.
+              assertTrue(focus.url.indexOf('iframe_outer') >= 0);
+
+              // Find the inner button and focus it.
+              var innerButton = focus.find({ attributes: { name: 'Inner' } });
+              innerButton.focus();
+            });
+          }
+        });
+      });
+    });
+  },
+];
+
+chrome.test.runTests(allTests);
diff --git a/chrome/test/data/extensions/api_test/browser_action/color/update4.html b/chrome/test/data/extensions/api_test/browser_action/color/update4.html
new file mode 100644
index 0000000..5ff3511
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/browser_action/color/update4.html
@@ -0,0 +1,7 @@
+<!--
+ * Copyright 2016 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+-->
+
+<script src="update4.js"></script>
diff --git a/chrome/test/data/extensions/api_test/browser_action/color/update4.js b/chrome/test/data/extensions/api_test/browser_action/color/update4.js
new file mode 100644
index 0000000..f8a15a3
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/browser_action/color/update4.js
@@ -0,0 +1,6 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+chrome.browserAction.setBadgeBackgroundColor({color: 'blue'});
+chrome.test.notifyPass();
diff --git a/chrome/test/data/extensions/platform_apps/background_page_navigation/nav-target.js b/chrome/test/data/extensions/platform_apps/background_page_navigation/nav-target.js
index e6e186b..77938ce8 100644
--- a/chrome/test/data/extensions/platform_apps/background_page_navigation/nav-target.js
+++ b/chrome/test/data/extensions/platform_apps/background_page_navigation/nav-target.js
@@ -4,4 +4,6 @@
 
 // We should never reach this page; if we have then it's a signal that we've
 // navigated away from the app page, and we should have the test fail.
-chrome.test.notifyFail('Navigated to ' + window.location.href);
+// TODO(lazyboy): Because of http://crbug.com/585570, we *do* reach this page,
+// enable the following line once the bug is fixed.
+//chrome.test.notifyFail('Navigated to ' + window.location.href);
diff --git a/chrome/test/data/extensions/platform_apps/background_page_navigation/test.js b/chrome/test/data/extensions/platform_apps/background_page_navigation/test.js
index f2060db..1da617e 100644
--- a/chrome/test/data/extensions/platform_apps/background_page_navigation/test.js
+++ b/chrome/test/data/extensions/platform_apps/background_page_navigation/test.js
@@ -25,7 +25,8 @@
     // Trying to open a local resource in a new window will fail.
     function windowOpenInAppRelativeURL() {
       var w = window.open(IN_APP_RELATIVE_URL);
-      chrome.test.assertTrue(!w);
+      // TODO(lazyboy): Enable the assert once http://crbug.com/585570 is fixed.
+      //chrome.test.assertTrue(!w);
       chrome.test.succeed();
     },
     // Trying to open a local resource in a new window will fail.
@@ -38,7 +39,8 @@
     // Similar to windowOpenInAppRelativeURL().
     function windowOpenInAppAbsoluteURL() {
       var w = window.open(IN_APP_ABSOLUTE_URL);
-      chrome.test.assertTrue(!w);
+      // TODO(lazyboy): Enable the assert once http://crbug.com/585570 is fixed.
+      //chrome.test.assertTrue(!w);
       chrome.test.succeed();
     },
     // Similar to openLinkToInAppRelativeURL().
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 9e99a98a..15828e8 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-8036.0.0
\ No newline at end of file
+8038.0.0
\ No newline at end of file
diff --git a/components/OWNERS b/components/OWNERS
index 7d08da7..4fb304f3a 100644
--- a/components/OWNERS
+++ b/components/OWNERS
@@ -312,6 +312,8 @@
 per-file storage_monitor.gypi=thestig@chromium.org
 per-file storage_monitor.gypi=vandebo@chromium.org
 
+per-file suggestions.gypi=file://components/suggestions/OWNERS
+
 per-file sync_driver*=pavely@chromium.org
 per-file sync_driver*=stanisc@chromium.org
 per-file sync_driver*=zea@chromium.org
diff --git a/components/arc.gypi b/components/arc.gypi
index 20f6600a..63e0236a 100644
--- a/components/arc.gypi
+++ b/components/arc.gypi
@@ -73,6 +73,8 @@
         'arc/test/fake_arc_bridge_instance.h',
         'arc/test/fake_arc_bridge_service.cc',
         'arc/test/fake_arc_bridge_service.h',
+        'arc/test/fake_notifications_instance.cc',
+        'arc/test/fake_notifications_instance.h',
       ],
     },
     {
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn
index 767d926..fdf0076 100644
--- a/components/arc/BUILD.gn
+++ b/components/arc/BUILD.gn
@@ -86,6 +86,8 @@
     "test/fake_arc_bridge_instance.h",
     "test/fake_arc_bridge_service.cc",
     "test/fake_arc_bridge_service.h",
+    "test/fake_notifications_instance.cc",
+    "test/fake_notifications_instance.h",
   ]
 
   deps = [
diff --git a/components/arc/test/fake_notifications_instance.cc b/components/arc/test/fake_notifications_instance.cc
new file mode 100644
index 0000000..3f5bea7b8
--- /dev/null
+++ b/components/arc/test/fake_notifications_instance.cc
@@ -0,0 +1,32 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/arc/test/fake_notifications_instance.h"
+
+namespace arc {
+
+FakeNotificationsInstance::FakeNotificationsInstance(
+    mojo::InterfaceRequest<NotificationsInstance> request)
+    : binding_(this, std::move(request)) {}
+
+FakeNotificationsInstance::~FakeNotificationsInstance() {}
+
+void FakeNotificationsInstance::SendNotificationEventToAndroid(
+    const mojo::String& key,
+    ArcNotificationEvent event) {
+  events_.emplace_back(key, event);
+}
+
+void FakeNotificationsInstance::Init(NotificationsHostPtr host_ptr) {}
+
+const std::vector<std::pair<mojo::String, ArcNotificationEvent>>&
+FakeNotificationsInstance::events() const {
+  return events_;
+}
+
+void FakeNotificationsInstance::WaitForIncomingMethodCall() {
+  binding_.WaitForIncomingMethodCall();
+}
+
+}  // namespace arc
diff --git a/components/arc/test/fake_notifications_instance.h b/components/arc/test/fake_notifications_instance.h
new file mode 100644
index 0000000..fdddc82
--- /dev/null
+++ b/components/arc/test/fake_notifications_instance.h
@@ -0,0 +1,39 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_ARC_TEST_FAKE_NOTIFICATIONS_INSTANCE_H_
+#define COMPONENTS_ARC_TEST_FAKE_NOTIFICATIONS_INSTANCE_H_
+
+#include "components/arc/common/notifications.mojom.h"
+#include "components/arc/test/fake_arc_bridge_instance.h"
+
+namespace arc {
+
+class FakeNotificationsInstance : public NotificationsInstance {
+ public:
+  FakeNotificationsInstance(
+      mojo::InterfaceRequest<NotificationsInstance> request);
+  ~FakeNotificationsInstance() override;
+
+  void Init(NotificationsHostPtr host_ptr) override;
+
+  void SendNotificationEventToAndroid(const mojo::String& key,
+                                      ArcNotificationEvent event) override;
+
+  const std::vector<std::pair<mojo::String, ArcNotificationEvent>>& events()
+      const;
+
+  void WaitForIncomingMethodCall();
+
+ private:
+  std::vector<std::pair<mojo::String, ArcNotificationEvent>> events_;
+
+  mojo::Binding<NotificationsInstance> binding_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeNotificationsInstance);
+};
+
+}  // namespace arc
+
+#endif  // COMPONENTS_ARC_TEST_FAKE_NOTIFICATIONS_INSTANCE_H_
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index f2675b1..a5412bf 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -477,7 +477,6 @@
       'password_manager/core/browser/password_bubble_experiment_unittest.cc',
       'password_manager/core/browser/password_form_manager_unittest.cc',
       'password_manager/core/browser/password_generation_manager_unittest.cc',
-      'password_manager/core/browser/password_manager_metrics_util_unittest.cc',
       'password_manager/core/browser/password_manager_settings_migration_experiment_unittest.cc',
       'password_manager/core/browser/password_manager_unittest.cc',
       'password_manager/core/browser/password_manager_util_unittest.cc',
diff --git a/components/domain_reliability/quic_error_mapping.cc b/components/domain_reliability/quic_error_mapping.cc
index 2d72593..d4ee1cf 100644
--- a/components/domain_reliability/quic_error_mapping.cc
+++ b/components/domain_reliability/quic_error_mapping.cc
@@ -87,8 +87,10 @@
   // We hit our overall connection timeout
   { net::QUIC_HANDSHAKE_TIMEOUT,
    "quic.connection.handshake_timed_out" },
-  // There was an error encountered migrating addresses
+  // There was an error encountered migrating addresses.
   { net::QUIC_ERROR_MIGRATING_ADDRESS, "quic.error_migrating_address" },
+  // There was an error encountered migrating port only.
+  { net::QUIC_ERROR_MIGRATING_PORT, "quic.error_migrating_port" },
   // There was an error while writing to the socket.
   { net::QUIC_PACKET_WRITE_ERROR, "quic.packet.write_error" },
   // There was an error while reading from the socket.
@@ -124,7 +126,8 @@
   { net::QUIC_TIMEOUTS_WITH_OPEN_STREAMS, "quic.timeouts_with_open_streams" },
   // Closed because we failed to serialize a packet.
   { net::QUIC_FAILED_TO_SERIALIZE_PACKET, "quic.failed_to_serialize_packet" },
-
+  // QUIC timed out after too many RTOs.
+  { net::QUIC_TOO_MANY_RTOS, "quic.too_many_rtos" },
   // Crypto errors.
 
   // Hanshake failed.
diff --git a/components/filesystem/BUILD.gn b/components/filesystem/BUILD.gn
index ff284242..e09c166 100644
--- a/components/filesystem/BUILD.gn
+++ b/components/filesystem/BUILD.gn
@@ -40,7 +40,6 @@
 
   deps = [
     ":lib",
-    ":manifest",
     "//base",
     "//components/filesystem/public/interfaces",
     "//mojo/common",
@@ -50,6 +49,10 @@
     "//mojo/services/tracing/public/cpp",
     "//mojo/shell/public/cpp",
   ]
+
+  data_deps = [
+    ":manifest",
+  ]
 }
 
 mojo_application_manifest("manifest") {
@@ -70,7 +73,6 @@
   ]
 
   deps = [
-    ":apptest_manifest",
     "//base",
     "//components/filesystem/public/interfaces",
     "//mojo/common",
@@ -80,6 +82,7 @@
   ]
 
   data_deps = [
+    ":apptest_manifest",
     ":filesystem",
   ]
 }
diff --git a/components/font_service/BUILD.gn b/components/font_service/BUILD.gn
index be7bd4f..92c1721 100644
--- a/components/font_service/BUILD.gn
+++ b/components/font_service/BUILD.gn
@@ -33,13 +33,16 @@
 
   deps = [
     ":lib",
-    ":manifest",
     "//base",
     "//mojo/common",
     "//mojo/common:common_base",
     "//mojo/public/cpp/bindings:callback",
     "//mojo/shell/public/cpp",
   ]
+
+  data_deps = [
+    ":manifest",
+  ]
 }
 
 mojo_application_manifest("manifest") {
diff --git a/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java b/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java
index 39f10a7f..462d515 100644
--- a/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java
+++ b/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java
@@ -118,6 +118,8 @@
         }.execute();
     }
 
+    // The caller of this function is responsible for setting the PathUtils Private Data Directory
+    // Suffix before calling onMessageReceived().
     public static void onMessageReceived(Context context, final String appId, final Bundle extras) {
         // TODO(johnme): Store message and redeliver later if Chrome is killed before delivery.
         ThreadUtils.assertOnUiThread();
diff --git a/components/invalidation/impl/android/javatests/src/org/chromium/components/invalidation/InvalidationClientServiceTest.java b/components/invalidation/impl/android/javatests/src/org/chromium/components/invalidation/InvalidationClientServiceTest.java
index bf5d075b..854765c 100644
--- a/components/invalidation/impl/android/javatests/src/org/chromium/components/invalidation/InvalidationClientServiceTest.java
+++ b/components/invalidation/impl/android/javatests/src/org/chromium/components/invalidation/InvalidationClientServiceTest.java
@@ -17,6 +17,7 @@
 import com.google.ipc.invalidation.external.client.types.ObjectId;
 
 import org.chromium.base.CollectionUtil;
+import org.chromium.base.PathUtils;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.base.test.util.AdvancedMockContext;
@@ -43,6 +44,7 @@
           ServiceTestCase<TestableInvalidationClientService> {
     /** Id used when creating clients. */
     private static final byte[] CLIENT_ID = new byte[]{0, 4, 7};
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "invalidation_test";
 
     /** Intents provided to {@link #startService}. */
     private List<Intent> mStartServiceIntents;
@@ -54,6 +56,8 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX,
+                getContext());
         mStartServiceIntents = new ArrayList<Intent>();
         setContext(new AdvancedMockContext(getContext()) {
             @Override
diff --git a/components/leveldb/BUILD.gn b/components/leveldb/BUILD.gn
index 32787b4..a68f5ecfc 100644
--- a/components/leveldb/BUILD.gn
+++ b/components/leveldb/BUILD.gn
@@ -39,7 +39,6 @@
 
   deps = [
     ":lib",
-    ":manifest",
     "//components/leveldb/public/interfaces",
     "//mojo/common",
     "//mojo/platform_handle:for_shared_library",
@@ -48,6 +47,10 @@
     "//mojo/services/tracing/public/cpp",
     "//mojo/shell/public/cpp",
   ]
+
+  data_deps = [
+    ":manifest",
+  ]
 }
 
 mojo_application_manifest("manifest") {
@@ -65,7 +68,6 @@
   ]
 
   deps = [
-    ":apptest_manifest",
     "//base",
     "//components/filesystem/public/interfaces",
     "//components/leveldb/public/interfaces",
@@ -76,6 +78,7 @@
   ]
 
   data_deps = [
+    ":apptest_manifest",
     ":leveldb",
     "//components/filesystem:filesystem",
   ]
diff --git a/components/mus/BUILD.gn b/components/mus/BUILD.gn
index 5891ffa9..0f54042 100644
--- a/components/mus/BUILD.gn
+++ b/components/mus/BUILD.gn
@@ -35,7 +35,6 @@
 
     deps = [
       ":lib",
-      ":manifest",
       "//mojo/platform_handle:for_shared_library",
       "//mojo/shell/public/cpp:sources",
     ]
@@ -43,6 +42,10 @@
     if (is_win) {
       deps += [ ":copy_gl_libraries" ]
     }
+
+    data_deps = [
+      ":manifest",
+    ]
   }
 
   mojo_application_manifest("manifest") {
diff --git a/components/mus/public/cpp/lib/in_flight_change.h b/components/mus/public/cpp/lib/in_flight_change.h
index 878ec77..f848ab3 100644
--- a/components/mus/public/cpp/lib/in_flight_change.h
+++ b/components/mus/public/cpp/lib/in_flight_change.h
@@ -39,6 +39,7 @@
   REMOVE_CHILD,
   REMOVE_TRANSIENT_WINDOW_FROM_PARENT,
   REORDER,
+  SET_MODAL,
   VISIBLE,
 };
 
diff --git a/components/mus/public/cpp/lib/window.cc b/components/mus/public/cpp/lib/window.cc
index 04dee4a..7078784 100644
--- a/components/mus/public/cpp/lib/window.cc
+++ b/components/mus/public/cpp/lib/window.cc
@@ -346,6 +346,15 @@
     tree_client()->RemoveTransientWindowFromParent(transient_window);
 }
 
+void Window::SetModal() {
+  if (is_modal_)
+    return;
+
+  LocalSetModal();
+  if (connection_)
+    tree_client()->SetModal(this);
+}
+
 Window* Window::GetChildById(Id id) {
   if (id == id_)
     return this;
@@ -493,6 +502,7 @@
       parent_(nullptr),
       stacking_target_(nullptr),
       transient_parent_(nullptr),
+      is_modal_(false),
       input_event_handler_(nullptr),
       viewport_metrics_(CreateEmptyViewportMetrics()),
       visible_(false),
@@ -588,6 +598,10 @@
   // TODO(fsamuel): We might want a notification here.
 }
 
+void Window::LocalSetModal() {
+  is_modal_ = true;
+}
+
 bool Window::LocalReorder(Window* relative, mojom::OrderDirection direction) {
   OrderChangedNotifier notifier(this, relative, direction);
   return ReorderImpl(this, relative, direction, &notifier);
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.cc b/components/mus/public/cpp/lib/window_tree_client_impl.cc
index cdcd7b6..47ea48e 100644
--- a/components/mus/public/cpp/lib/window_tree_client_impl.cc
+++ b/components/mus/public/cpp/lib/window_tree_client_impl.cc
@@ -217,6 +217,13 @@
   tree_->RemoveTransientWindowFromParent(change_id, window->id());
 }
 
+void WindowTreeClientImpl::SetModal(Window* window) {
+  DCHECK(tree_);
+  const uint32_t change_id = ScheduleInFlightChange(
+      make_scoped_ptr(new CrashInFlightChange(window, ChangeType::SET_MODAL)));
+  tree_->SetModal(change_id, window->id());
+}
+
 void WindowTreeClientImpl::Reorder(Window* window,
                                    Id relative_window_id,
                                    mojom::OrderDirection direction) {
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.h b/components/mus/public/cpp/lib/window_tree_client_impl.h
index 7e26819..5dba11c 100644
--- a/components/mus/public/cpp/lib/window_tree_client_impl.h
+++ b/components/mus/public/cpp/lib/window_tree_client_impl.h
@@ -66,6 +66,8 @@
   void AddTransientWindow(Window* window, Id transient_window_id);
   void RemoveTransientWindowFromParent(Window* window);
 
+  void SetModal(Window* window);
+
   void Reorder(Window* window,
                Id relative_window_id,
                mojom::OrderDirection direction);
diff --git a/components/mus/public/cpp/window.h b/components/mus/public/cpp/window.h
index 92db4c7e..a04af04 100644
--- a/components/mus/public/cpp/window.h
+++ b/components/mus/public/cpp/window.h
@@ -185,6 +185,9 @@
   const Window* transient_parent() const { return transient_parent_; }
   const Children& transient_children() const { return transient_children_; }
 
+  void SetModal();
+  bool is_modal() const { return is_modal_; }
+
   Window* GetChildById(Id id);
 
   void SetTextInputState(mojo::TextInputStatePtr state);
@@ -243,6 +246,7 @@
   void LocalRemoveChild(Window* child);
   void LocalAddTransientWindow(Window* transient_window);
   void LocalRemoveTransientWindow(Window* transient_window);
+  void LocalSetModal();
   // Returns true if the order actually changed.
   bool LocalReorder(Window* relative, mojom::OrderDirection direction);
   void LocalSetBounds(const gfx::Rect& old_bounds, const gfx::Rect& new_bounds);
@@ -297,6 +301,8 @@
   Window* transient_parent_;
   Children transient_children_;
 
+  bool is_modal_;
+
   base::ObserverList<WindowObserver> observers_;
   InputEventHandler* input_event_handler_;
 
diff --git a/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc b/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc
index 897c484..77219ee 100644
--- a/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc
+++ b/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc
@@ -109,8 +109,8 @@
     return true;
   }
 
-  void NotifyUserAutoSignin(
-      ScopedVector<autofill::PasswordForm> local_forms) override {
+  void NotifyUserAutoSignin(ScopedVector<autofill::PasswordForm> local_forms,
+                            const GURL& origin) override {
     EXPECT_FALSE(local_forms.empty());
     NotifyUserAutoSigninPtr(local_forms.get());
   }
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index c672db0..8819e403 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -211,7 +211,6 @@
     "password_bubble_experiment_unittest.cc",
     "password_form_manager_unittest.cc",
     "password_generation_manager_unittest.cc",
-    "password_manager_metrics_util_unittest.cc",
     "password_manager_settings_migration_experiment_unittest.cc",
     "password_manager_unittest.cc",
     "password_manager_util_unittest.cc",
diff --git a/components/password_manager/core/browser/credential_manager_pending_request_task.cc b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
index 3d83f496..b2c99e2 100644
--- a/components/password_manager/core/browser/credential_manager_pending_request_task.cc
+++ b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
@@ -107,7 +107,8 @@
                         local_results[0]->federation_origin.unique()
                             ? CredentialType::CREDENTIAL_TYPE_PASSWORD
                             : CredentialType::CREDENTIAL_TYPE_FEDERATED);
-    delegate_->client()->NotifyUserAutoSignin(std::move(local_results));
+    delegate_->client()->NotifyUserAutoSignin(std::move(local_results),
+                                              origin_);
     delegate_->SendCredential(id_, info);
     return;
   }
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
index 620d14b..65d8f00 100644
--- a/components/password_manager/core/browser/password_manager.cc
+++ b/components/password_manager/core/browser/password_manager.cc
@@ -163,7 +163,6 @@
       user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
   registry->RegisterBooleanPref(prefs::kPasswordManagerAllowShowPasswords,
                                 true);
-  registry->RegisterListPref(prefs::kPasswordManagerGroupsForDomains);
 #if defined(OS_MACOSX)
   registry->RegisterIntegerPref(prefs::kKeychainMigrationStatus,
                                 static_cast<int>(MigrationStatus::NOT_STARTED));
@@ -370,16 +369,6 @@
   UMA_HISTOGRAM_ENUMERATION(
       "PasswordManager.ProvisionalSaveFailure", failure, MAX_FAILURE_VALUE);
 
-  std::string group_name =
-      metrics_util::GroupIdToString(metrics_util::MonitoredDomainGroupId(
-          form_origin.host(), client_->GetPrefs()));
-  if (!group_name.empty()) {
-    metrics_util::LogUMAHistogramEnumeration(
-        "PasswordManager.ProvisionalSaveFailure_" + group_name,
-        failure,
-        MAX_FAILURE_VALUE);
-  }
-
   if (logger) {
     switch (failure) {
       case SAVING_DISABLED:
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
index c9c5549a..46485f6 100644
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -105,11 +105,12 @@
   virtual void GeneratePassword();
 
   // Informs the embedder that automatic signing in just happened. The form
-  // returned to the site is |local_forms[0]|. |local_forms| and
-  // |federated_forms| contain all the local and federated credentials for the
-  // site.
+  // returned to the site is |local_forms[0]|. |local_forms| contains all the
+  // local credentials for the site. |origin| is a URL of the site the user was
+  // auto signed in to.
   virtual void NotifyUserAutoSignin(
-      ScopedVector<autofill::PasswordForm> local_forms) = 0;
+      ScopedVector<autofill::PasswordForm> local_forms,
+      const GURL& origin) = 0;
 
   // Inform the embedder that automatic signin would have happened if the user
   // had been through the first-run experience to ensure their opt-in. |form|
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.cc b/components/password_manager/core/browser/password_manager_metrics_util.cc
index 5e4c0c6..f6aa337 100644
--- a/components/password_manager/core/browser/password_manager_metrics_util.cc
+++ b/components/password_manager/core/browser/password_manager_metrics_util.cc
@@ -24,82 +24,6 @@
 
 namespace metrics_util {
 
-namespace {
-
-// The number of domain groups.
-const size_t kNumGroups = 2u * kGroupsPerDomain;
-
-// |kDomainMapping| contains each monitored website together with all ids of
-// groups which contain the website. Each website appears in
-// |kGroupsPerDomain| groups, and each group includes an equal number of
-// websites, so that no two websites have the same set of groups that they
-// belong to. All ids are in the range [1, |kNumGroups|].
-// For more information about the algorithm used see http://goo.gl/vUuFd5.
-struct DomainGroupsPair {
-  const char* const domain_name;
-  const size_t group_ids[kGroupsPerDomain];
-};
-const DomainGroupsPair kDomainMapping[] = {
-    {"google.com", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}},
-    {"yahoo.com", {1, 2, 3, 4, 5, 11, 12, 13, 14, 15}},
-    {"baidu.com", {1, 2, 3, 4, 6, 7, 11, 12, 16, 17}},
-    {"wikipedia.org", {1, 2, 3, 4, 5, 6, 11, 12, 16, 18}},
-    {"linkedin.com", {1, 6, 8, 11, 13, 14, 15, 16, 17, 19}},
-    {"twitter.com", {5, 6, 7, 8, 9, 11, 13, 17, 19, 20}},
-    {"facebook.com", {7, 8, 9, 10, 13, 14, 16, 17, 18, 20}},
-    {"amazon.com", {2, 5, 9, 10, 12, 14, 15, 18, 19, 20}},
-    {"ebay.com", {3, 7, 9, 10, 14, 15, 17, 18, 19, 20}},
-    {"tumblr.com", {4, 8, 10, 12, 13, 15, 16, 18, 19, 20}},
-};
-const size_t kNumDomains = arraysize(kDomainMapping);
-
-// For every monitored domain, this function chooses which of the groups
-// containing that domain should be used for reporting. That number is chosen
-// randomly and stored in the user's preferences.
-size_t GetGroupIndex(size_t domain_index, PrefService* pref_service) {
-  DCHECK_LT(domain_index, kNumDomains);
-
-  const base::ListValue* group_indices =
-      pref_service->GetList(prefs::kPasswordManagerGroupsForDomains);
-  int result = 0;
-  if (!group_indices->GetInteger(domain_index, &result)) {
-    ListPrefUpdate group_indices_updater(
-        pref_service, prefs::kPasswordManagerGroupsForDomains);
-    // This value has not been generated yet.
-    result = base::checked_cast<int>(base::RandGenerator(kGroupsPerDomain));
-    group_indices_updater->Set(domain_index, new FundamentalValue(result));
-  }
-  return base::checked_cast<size_t>(result);
-}
-
-}  // namespace
-
-size_t MonitoredDomainGroupId(const std::string& url_host,
-                              PrefService* pref_service) {
-  GURL url(url_host);
-  for (size_t i = 0; i < kNumDomains; ++i) {
-    if (url.DomainIs(kDomainMapping[i].domain_name))
-      return kDomainMapping[i].group_ids[GetGroupIndex(i, pref_service)];
-  }
-  return 0;
-}
-
-void LogUMAHistogramEnumeration(const std::string& name,
-                                int sample,
-                                int boundary_value) {
-  DCHECK_LT(sample, boundary_value);
-
-  // Note: This leaks memory, which is expected behavior.
-  base::HistogramBase* histogram =
-      base::LinearHistogram::FactoryGet(
-          name,
-          1,
-          boundary_value,
-          boundary_value + 1,
-          base::HistogramBase::kUmaTargetedHistogramFlag);
-  histogram->Add(sample);
-}
-
 void LogUMAHistogramBoolean(const std::string& name, bool sample) {
   // Note: This leaks memory, which is expected behavior.
   base::HistogramBase* histogram = base::BooleanHistogram::FactoryGet(
@@ -107,35 +31,6 @@
   histogram->AddBoolean(sample);
 }
 
-std::string GroupIdToString(size_t group_id) {
-  DCHECK_LE(group_id, kNumGroups);
-  if (group_id > 0)
-    return "group_" + base::SizeTToString(group_id);
-  return std::string();
-}
-
-void LogUIDismissalReason(ResponseType type) {
-  UIDismissalReason reason = NO_DIRECT_INTERACTION;
-  switch (type) {
-    case NO_RESPONSE:
-      reason = NO_DIRECT_INTERACTION;
-      break;
-    case REMEMBER_PASSWORD:
-      reason = CLICKED_SAVE;
-      break;
-    case NEVER_REMEMBER_PASSWORD:
-      reason = CLICKED_NEVER;
-      break;
-    case INFOBAR_DISMISSED:
-      reason = CLICKED_CANCEL;
-      break;
-    case NUM_RESPONSE_TYPES:
-      NOTREACHED();
-      break;
-  }
-  LogUIDismissalReason(reason);
-}
-
 void LogUIDismissalReason(UIDismissalReason reason) {
   UMA_HISTOGRAM_ENUMERATION("PasswordManager.UIDismissalReason",
                             reason,
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.h b/components/password_manager/core/browser/password_manager_metrics_util.h
index 354a685..1360f204 100644
--- a/components/password_manager/core/browser/password_manager_metrics_util.h
+++ b/components/password_manager/core/browser/password_manager_metrics_util.h
@@ -9,8 +9,6 @@
 
 #include <string>
 
-class PrefService;
-
 namespace password_manager {
 
 namespace metrics_util {
@@ -123,48 +121,13 @@
   MULTI_ACCOUNT_UPDATE_BUBBLE_USER_ACTION_COUNT
 };
 
-// We monitor the performance of the save password heuristic for a handful of
-// domains. For privacy reasons we are not reporting UMA signals by domain, but
-// by a domain group. A domain group can contain multiple domains, and a domain
-// can be contained in multiple groups.
-// For more information see http://goo.gl/vUuFd5.
-
-// The number of groups in which each monitored website appears.
-// It is a half of the total number of groups.
-const size_t kGroupsPerDomain = 10u;
-
-// Check whether the |url_host| is monitored or not. If yes, we return
-// the id of the group which contains the domain name otherwise
-// returns 0. |pref_service| needs to be the profile preference service.
-size_t MonitoredDomainGroupId(const std::string& url_host,
-                              PrefService* pref_service);
-
-// A version of the UMA_HISTOGRAM_ENUMERATION macro that allows the |name|
-// to vary over the program's runtime.
-void LogUMAHistogramEnumeration(const std::string& name,
-                                int sample,
-                                int boundary_value);
-
 // A version of the UMA_HISTOGRAM_BOOLEAN macro that allows the |name|
 // to vary over the program's runtime.
 void LogUMAHistogramBoolean(const std::string& name, bool sample);
 
-// Returns a string which contains group_|group_id|. If the
-// |group_id| corresponds to an unmonitored domain returns an empty string.
-std::string GroupIdToString(size_t group_id);
-
 // Log the |reason| a user dismissed the password manager UI.
 void LogUIDismissalReason(UIDismissalReason reason);
 
-// Given a ResponseType, log the appropriate UIResponse. We'll use this
-// mapping to migrate from "PasswordManager.InfoBarResponse" to
-// "PasswordManager.UIDismissalReason" so we can accurately evaluate the
-// impact of the bubble UI.
-//
-// TODO(mkwst): Drop this (and the infobar metric itself) once the new metric
-// has rolled out to stable.
-void LogUIDismissalReason(ResponseType type);
-
 // Log the appropriate display disposition.
 void LogUIDisplayDisposition(UIDisplayDisposition disposition);
 
diff --git a/components/password_manager/core/browser/password_manager_metrics_util_unittest.cc b/components/password_manager/core/browser/password_manager_metrics_util_unittest.cc
deleted file mode 100644
index 8efb55d..0000000
--- a/components/password_manager/core/browser/password_manager_metrics_util_unittest.cc
+++ /dev/null
@@ -1,82 +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 "components/password_manager/core/browser/password_manager_metrics_util.h"
-
-#include <stddef.h>
-
-#include <map>
-
-#include "base/macros.h"
-#include "base/values.h"
-#include "components/password_manager/core/common/password_manager_pref_names.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/scoped_user_pref_update.h"
-#include "components/prefs/testing_pref_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace password_manager {
-
-class PasswordManagerMetricsUtilTest : public testing::Test {
- protected:
-  void SetUp() override {
-    testing::Test::SetUp();
-    prefs_.registry()->RegisterListPref(
-        prefs::kPasswordManagerGroupsForDomains);
-  }
-
-  bool IsMonitored(const char* url_host) {
-    size_t group_id = metrics_util::MonitoredDomainGroupId(url_host, &prefs_);
-    return group_id > 0;
-  }
-
-  TestingPrefServiceSimple prefs_;
-};
-
-TEST_F(PasswordManagerMetricsUtilTest, MonitoredDomainGroupAssigmentTest) {
-  const char* const kMonitoredWebsites[] = {
-      "https://www.google.com",   "https://www.yahoo.com",
-      "https://www.baidu.com",    "https://www.wikipedia.org",
-      "https://www.linkedin.com", "https://www.twitter.com",
-      "https://www.facebook.com", "https://www.amazon.com",
-      "https://www.ebay.com",     "https://www.tumblr.com",
-  };
-  const size_t kMonitoredWebsitesLength = arraysize(kMonitoredWebsites);
-
-  // |groups| maps the group id to the number of times the group gets assigned.
-  std::map<size_t, size_t> groups;
-
-  // Provide all possible values of the group id parameter for each monitored
-  // website.
-  for (size_t i = 0; i < kMonitoredWebsitesLength; ++i) {
-    for (size_t j = 0; j < metrics_util::kGroupsPerDomain; ++j) {
-      {  // Set the group index for domain |i| to |j|.
-        ListPrefUpdate group_indices(&prefs_,
-                                     prefs::kPasswordManagerGroupsForDomains);
-        group_indices->Set(i, new base::FundamentalValue(static_cast<int>(j)));
-      }  // At the end of the scope the prefs get updated.
-
-      ++groups[metrics_util::MonitoredDomainGroupId(kMonitoredWebsites[i],
-                                                    &prefs_)];
-    }
-  }
-  // None of the monitored websites should have been assigned group ID 0.
-  EXPECT_EQ(0u, groups.count(0));
-
-  // Check if all groups get assigned the same number of times.
-  size_t number_of_assigments = groups.begin()->second;
-  for (auto it = groups.begin(); it != groups.end(); ++it) {
-    EXPECT_EQ(it->second, number_of_assigments) << " group id = " << it->first;
-  }
-}
-
-TEST_F(PasswordManagerMetricsUtilTest, MonitoredDomainGroupTest) {
-  EXPECT_TRUE(IsMonitored("https://www.linkedin.com"));
-  EXPECT_TRUE(IsMonitored("https://www.amazon.com"));
-  EXPECT_TRUE(IsMonitored("https://www.facebook.com"));
-  EXPECT_TRUE(IsMonitored("http://wikipedia.org"));
-  EXPECT_FALSE(IsMonitored("http://thisisnotwikipedia.org"));
-}
-
-}  // namespace password_manager
diff --git a/components/password_manager/core/browser/stub_password_manager_client.cc b/components/password_manager/core/browser/stub_password_manager_client.cc
index 05491e73..020ab31 100644
--- a/components/password_manager/core/browser/stub_password_manager_client.cc
+++ b/components/password_manager/core/browser/stub_password_manager_client.cc
@@ -42,8 +42,8 @@
 }
 
 void StubPasswordManagerClient::NotifyUserAutoSignin(
-    ScopedVector<autofill::PasswordForm> local_forms) {
-}
+    ScopedVector<autofill::PasswordForm> local_forms,
+    const GURL& origin) {}
 
 void StubPasswordManagerClient::NotifyUserCouldBeAutoSignedIn(
     scoped_ptr<autofill::PasswordForm> form) {}
diff --git a/components/password_manager/core/browser/stub_password_manager_client.h b/components/password_manager/core/browser/stub_password_manager_client.h
index 0d891f1..6db2c8e 100644
--- a/components/password_manager/core/browser/stub_password_manager_client.h
+++ b/components/password_manager/core/browser/stub_password_manager_client.h
@@ -30,8 +30,8 @@
       const GURL& origin,
       base::Callback<void(const password_manager::CredentialInfo&)> callback)
       override;
-  void NotifyUserAutoSignin(
-      ScopedVector<autofill::PasswordForm> local_forms) override;
+  void NotifyUserAutoSignin(ScopedVector<autofill::PasswordForm> local_forms,
+                            const GURL& origin) override;
   void NotifyUserCouldBeAutoSignedIn(
       scoped_ptr<autofill::PasswordForm>) override;
   void NotifySuccessfulLoginWithExistingPassword(
diff --git a/components/password_manager/core/common/password_manager_pref_names.cc b/components/password_manager/core/common/password_manager_pref_names.cc
index a620c50e..96300b5 100644
--- a/components/password_manager/core/common/password_manager_pref_names.cc
+++ b/components/password_manager/core/common/password_manager_pref_names.cc
@@ -28,8 +28,6 @@
 const char kPasswordManagerAllowShowPasswords[] =
     "profile.password_manager_allow_show_passwords";
 const char kPasswordManagerSavingEnabled[] = "profile.password_manager_enabled";
-const char kPasswordManagerGroupsForDomains[] =
-    "profile.password_manager_groups_for_domains";
 
 const char kWasAutoSignInFirstRunExperienceShown[] =
     "profile.was_auto_sign_in_first_run_experience_shown";
diff --git a/components/password_manager/core/common/password_manager_pref_names.h b/components/password_manager/core/common/password_manager_pref_names.h
index eb66102..0ec526b 100644
--- a/components/password_manager/core/common/password_manager_pref_names.h
+++ b/components/password_manager/core/common/password_manager_pref_names.h
@@ -59,12 +59,6 @@
 // See http://crbug.com/392387
 extern const char kPasswordManagerSavingEnabled[];
 
-// A list of numbers. Each number corresponds to one of the domains monitored
-// for save-password-prompt breakages. That number is a random index into
-// the array of groups containing the monitored domain. That group should be
-// used for reporting that domain.
-extern const char kPasswordManagerGroupsForDomains[];
-
 // Boolean that indicated whether first run experience for the auto sign-in
 // prompt was shown or not.
 extern const char kWasAutoSignInFirstRunExperienceShown[];
diff --git a/components/profile_service/BUILD.gn b/components/profile_service/BUILD.gn
index 6fd497b..cdde7a0 100644
--- a/components/profile_service/BUILD.gn
+++ b/components/profile_service/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//mojo/public/mojo_application.gni")
-import("//mojo/public/mojo_application_manifest.gni")
 
 source_set("lib") {
   sources = [
diff --git a/components/resource_provider/BUILD.gn b/components/resource_provider/BUILD.gn
index bcdb01a..5133229 100644
--- a/components/resource_provider/BUILD.gn
+++ b/components/resource_provider/BUILD.gn
@@ -71,12 +71,15 @@
 
     deps = [
       ":lib",
-      ":manifest",
       "//base",
       "//components/resource_provider/public/interfaces",
       "//mojo/shell/public/cpp",
       "//url",
     ]
+
+    data_deps = [
+      ":manifest",
+    ]
   }
 
   mojo_application_manifest("manifest") {
@@ -137,7 +140,6 @@
   ]
 
   deps = [
-    ":apptest_manifest",
     "//base",
     "//base/test:test_config",
     "//components/resource_provider/public/cpp",
@@ -147,6 +149,7 @@
   ]
 
   data_deps = [
+    ":apptest_manifest",
     ":resource_provider",
   ]
 }
diff --git a/components/version_info.gypi b/components/version_info.gypi
index 472f1d8..d81d85d 100644
--- a/components/version_info.gypi
+++ b/components/version_info.gypi
@@ -4,12 +4,6 @@
 
 {
   'variables': {
-    # Some plaform want to override part of the version number generation
-    # (for example iOS uses a different value for PATCH level for canary).
-    # This can be done settings "extra_version_path" variable to the path
-    # of a file with the corresponding value overrides. If present it will
-    # be loaded after all other input files.
-    'extra_version_name': '',
     'conditions': [
       ['branding == "Chrome"', {
         'use_unofficial_version_number%': 0,
@@ -93,35 +87,8 @@
             '<(template_input_path)',
             '<@(_outputs)',
           ],
-          'conditions': [
-            ['extra_version_name!=""', {
-              'variables': {
-                'extra_version_flags': [
-                  '-f', '<(extra_version_name)',
-                ],
-              },
-              'inputs': [
-                '<(extra_version_name)'
-              ],
-            }],
-          ],
         },
       ],
     },
   ],
-  'conditions': [
-    ['OS=="ios"', {
-      'variables': {
-        # Use nested 'variables' to workaround how variables work with gyp (no
-        # determined ordering and thuse it is not possible to define a variable
-        # in function of another).
-        'variables': {
-          # Path to the file used to override the version PATH level on iOS.
-          # Default to ios/build/util/VERSION.
-          'ios_extra_version_path%': '../ios/build/util/VERSION',
-        },
-        'extra_version_name': '<(ios_extra_version_path)'
-      },
-    }],
-  ],
 }
diff --git a/components/version_info/BUILD.gn b/components/version_info/BUILD.gn
index 7f51c0a4..6c043e53 100644
--- a/components/version_info/BUILD.gn
+++ b/components/version_info/BUILD.gn
@@ -6,12 +6,6 @@
 import("//chrome/version.gni")
 
 declare_args() {
-  if (is_ios) {
-    # Path to the file used to override the version PATH level on iOS.
-    # Default to ios/build/util/VERSION.
-    ios_extra_version_path = "//ios/build/util/VERSION"
-  }
-
   use_unofficial_version_number = !is_chrome_branded
 }
 
@@ -36,19 +30,4 @@
 process_version("generate_version_info") {
   template_file = "version_info_values.h.version"
   output = "$target_gen_dir/version_info_values.h"
-
-  if (is_ios) {
-    # iOS overrides PATCH level of the version with the value from the file
-    # named by ios_version_path, however, this needs to be the last argument
-    # to the version.py script, so it cannot be added to the sources variable
-    # and instead need to be managed manually.
-
-    inputs = [
-      ios_extra_version_path,
-    ]
-    extra_args = [
-      "-f",
-      rebase_path(ios_extra_version_path, root_build_dir),
-    ]
-  }
 }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index a455bac..57aed3d0 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -23,7 +23,6 @@
 
   # Shared deps. See also non-iOS deps below.
   deps = [
-    ":chrome_renderer_manifest",
     "//base",
     "//base:base_static",
     "//components/mime_util",
@@ -70,6 +69,10 @@
     "//ui/snapshot",
   ]
 
+  data_deps = [
+    ":chrome_renderer_manifest",
+  ]
+
   if (is_ios) {
     # iOS doesn't get the normal file list and only takes these whitelisted
     # files.
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
index 200c337..b74fb1d 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_blink.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -39,7 +39,7 @@
     base::DictionaryValue* dict) {
   dict->SetInteger("id", node.GetId());
 
-  dict->SetString("role", ui::ToString(node.GetData().role));
+  dict->SetString("internalRole", ui::ToString(node.GetData().role));
 
   dict->SetInteger("boundsX", node.GetData().location.x());
   dict->SetInteger("boundsY", node.GetData().location.y());
@@ -112,7 +112,7 @@
   }
 
   base::string16 role_value;
-  dict.GetString("role", &role_value);
+  dict.GetString("internalRole", &role_value);
   WriteAttribute(true, base::UTF16ToUTF8(role_value), &line);
 
   for (int state_index = ui::AX_STATE_NONE;
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index 3cc4c5e..09daafe 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -303,7 +303,10 @@
       class_name = "android.app.Dialog";
       break;
     case ui::AX_ROLE_ROOT_WEB_AREA:
-      class_name = "android.webkit.WebView";
+      if (GetParent() == nullptr)
+        class_name = "android.webkit.WebView";
+      else
+        class_name = "android.view.View";
       break;
     case ui::AX_ROLE_MENU_ITEM:
     case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
@@ -935,13 +938,13 @@
   // Figure out the bounding box of the visible portion of this scrollable
   // view so we know how much to scroll by.
   gfx::Rect bounds;
-  if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA) {
+  if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA && !GetParent()) {
     // If this is the root web area, use the bounds of the view to determine
     // how big one page is.
     if (!manager()->delegate())
       return false;
     bounds = manager()->delegate()->AccessibilityGetViewBounds();
-  } else if (GetRole() == ui::AX_ROLE_WEB_AREA) {
+  } else if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA && GetParent()) {
     // If this is a web area inside of an iframe, try to use the bounds of
     // the containing element.
     BrowserAccessibility* parent = GetParent();
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index c6b65e6..ebf3a99 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -125,6 +125,8 @@
       tree_(new ui::AXSerializableTree()),
       user_is_navigating_away_(false),
       osk_state_(OSK_ALLOWED),
+      last_focused_node_(nullptr),
+      last_focused_manager_(nullptr),
       ax_tree_id_(AXTreeIDRegistry::kNoAXTreeID),
       parent_node_id_from_parent_tree_(0) {
   tree_->SetDelegate(this);
@@ -173,6 +175,40 @@
   return update;
 }
 
+void BrowserAccessibilityManager::FireFocusEventsIfNeeded() {
+  BrowserAccessibility* focus = GetFocus();
+  if (delegate_ && !delegate_->AccessibilityViewHasFocus())
+    focus = nullptr;
+
+  if (!CanFireEvents())
+    focus = nullptr;
+
+  // Don't allow the document to be focused if it has no children and
+  // hasn't finished loading yet. Wait for at least a tiny bit of content,
+  // or for the document to actually finish loading.
+  if (focus &&
+      focus == focus->manager()->GetRoot() &&
+      focus->PlatformChildCount() == 0 &&
+      !focus->HasState(ui::AX_STATE_BUSY) &&
+      !focus->manager()->GetTreeData().loaded) {
+    focus = nullptr;
+  }
+
+  if (focus && focus != last_focused_node_)
+    FireFocusEvent(focus);
+
+  last_focused_node_ = focus;
+  last_focused_manager_ = focus ? focus->manager() : nullptr;
+}
+
+bool BrowserAccessibilityManager::CanFireEvents() {
+  return true;
+}
+
+void BrowserAccessibilityManager::FireFocusEvent(BrowserAccessibility* node) {
+  NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, node);
+}
+
 BrowserAccessibility* BrowserAccessibilityManager::GetRoot() {
   // tree_ can be null during destruction.
   if (!tree_)
@@ -238,15 +274,15 @@
 }
 
 void BrowserAccessibilityManager::OnWindowFocused() {
-  BrowserAccessibility* focus = GetFocus();
-  if (focus)
-    NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, focus);
+  if (this == GetRootManager())
+    FireFocusEventsIfNeeded();
 }
 
 void BrowserAccessibilityManager::OnWindowBlurred() {
-  BrowserAccessibility* focus = GetFocus();
-  if (focus)
-    NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, focus);
+  if (this == GetRootManager()) {
+    last_focused_node_ = nullptr;
+    last_focused_manager_ = nullptr;
+  }
 }
 
 void BrowserAccessibilityManager::UserIsNavigatingAway() {
@@ -294,7 +330,14 @@
     }
   }
 
-  // Now iterate over the events again and fire the events.
+  // Based on the changes to the tree, first fire focus events if needed.
+  // Screen readers might not do the right thing if they're not aware of what
+  // has focus, so always try that first. Nothing will be fired if the window
+  // itself isn't focused or if focus hasn't changed.
+  GetRootManager()->FireFocusEventsIfNeeded();
+
+  // Now iterate over the events again and fire the events other than focus
+  // events.
   for (uint32_t index = 0; index < details.size(); index++) {
     const AXEventNotificationDetails& detail = details[index];
 
@@ -311,13 +354,18 @@
           osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED)
         osk_state_ = OSK_ALLOWED;
 
-      // Don't send a native focus event if the window itself doesn't
-      // have focus.
-      if (!NativeViewHasFocus())
+      bool is_menu_list_option =
+          node->data().role == ui::AX_ROLE_MENU_LIST_OPTION;
+
+      // Skip all focus events other than ones on menu list options;
+      // we've already handled them, above. Menu list options are a weird
+      // exception because the menu list itself has focus but we need to fire
+      // focus events on the individual options.
+      if (!is_menu_list_option)
         continue;
     }
 
-    // Send the event event to the operating system.
+    // Fire the native event.
     NotifyAccessibilityEvent(event_type, GetFromAXNode(node));
   }
 }
@@ -395,10 +443,21 @@
 }
 
 BrowserAccessibility* BrowserAccessibilityManager::GetFocus() {
-  int32_t focus_id = GetTreeData().focus_id;
-  BrowserAccessibility* obj = GetFromID(focus_id);
+  BrowserAccessibilityManager* root_manager = GetRootManager();
+  if (!root_manager)
+    root_manager = this;
+  int32_t focused_tree_id = root_manager->GetTreeData().focused_tree_id;
+
+  BrowserAccessibilityManager* focused_manager = nullptr;
+  if (focused_tree_id)
+    focused_manager =BrowserAccessibilityManager::FromID(focused_tree_id);
+  if (!focused_manager)
+    focused_manager = root_manager;
+
+  int32_t focus_id = focused_manager->GetTreeData().focus_id;
+  BrowserAccessibility* obj = focused_manager->GetFromID(focus_id);
   if (!obj)
-    return GetRoot();
+    return focused_manager->GetRoot();
 
   if (obj->HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
     BrowserAccessibilityManager* child_manager =
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h
index da1ded8d..908029b 100644
--- a/content/browser/accessibility/browser_accessibility_manager.h
+++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -138,6 +138,18 @@
   virtual void NotifyAccessibilityEvent(
       ui::AXEvent event_type, BrowserAccessibility* node) { }
 
+  // Checks whether focus has changed since the last time it was checked,
+  // taking into account whether the window has focus and which frame within
+  // the frame tree has focus. If focus has changed, calls FireFocusEvent.
+  void FireFocusEventsIfNeeded();
+
+  // Return whether or not we are currently able to fire events.
+  virtual bool CanFireEvents();
+
+  // Fire a focus event. Virtual so that some platforms can customize it,
+  // like firing a focus event on the root first, on Windows.
+  virtual void FireFocusEvent(BrowserAccessibility* node);
+
   // Return a pointer to the root of the tree, does not make a new reference.
   BrowserAccessibility* GetRoot();
 
@@ -379,6 +391,16 @@
 
   BrowserAccessibilityFindInPageInfo find_in_page_info_;
 
+  // These are only used by the root BrowserAccessibilityManager of a
+  // frame tree. Stores the last focused node and last focused manager so
+  // that when focus might have changed we can figure out whether we need
+  // to fire a focus event.
+  //
+  // NOTE: these pointers are not cleared, so they should never be
+  // dereferenced, only used for comparison.
+  BrowserAccessibility* last_focused_node_;
+  BrowserAccessibilityManager* last_focused_manager_;
+
   // The global ID of this accessibility tree.
   AXTreeIDRegistry::AXTreeID ax_tree_id_;
 
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
index e4c537c..c614d78d 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -148,7 +148,7 @@
 
 BrowserAccessibilityManagerAndroid::~BrowserAccessibilityManagerAndroid() {
   JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+  ScopedJavaLocalRef<jobject> obj = GetJavaRefFromRootManager();
   if (obj.is_null())
     return;
 
@@ -184,7 +184,7 @@
     ui::AXEvent event_type,
     BrowserAccessibility* node) {
   JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+  ScopedJavaLocalRef<jobject> obj = GetJavaRefFromRootManager();
   if (obj.is_null())
     return;
 
@@ -277,8 +277,8 @@
   // nodes changed location, just send a single notification after a short
   // delay (to batch them), rather than lots of individual notifications.
   if (params.size() > 3) {
+    ScopedJavaLocalRef<jobject> obj = GetJavaRefFromRootManager();
     JNIEnv* env = AttachCurrentThread();
-    ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
     if (obj.is_null())
       return;
     Java_BrowserAccessibilityManager_sendDelayedWindowContentChangedEvent(
@@ -670,7 +670,7 @@
 void BrowserAccessibilityManagerAndroid::HandleHoverEvent(
     BrowserAccessibility* node) {
   JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+  ScopedJavaLocalRef<jobject> obj = GetJavaRefFromRootManager();
   if (obj.is_null())
     return;
 
@@ -907,9 +907,12 @@
     ui::AXTree* tree,
     bool root_changed,
     const std::vector<ui::AXTreeDelegate::Change>& changes) {
+  BrowserAccessibilityManager::OnAtomicUpdateFinished(
+      tree, root_changed, changes);
+
   if (root_changed) {
     JNIEnv* env = AttachCurrentThread();
-    ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+    ScopedJavaLocalRef<jobject> obj = GetJavaRefFromRootManager();
     if (obj.is_null())
       return;
 
@@ -929,6 +932,18 @@
       BrowserAccessibility::GetFromUniqueID(unique_id));
 }
 
+ScopedJavaLocalRef<jobject>
+BrowserAccessibilityManagerAndroid::GetJavaRefFromRootManager() {
+  BrowserAccessibilityManagerAndroid* root_manager =
+      static_cast<BrowserAccessibilityManagerAndroid*>(
+          GetRootManager());
+  if (!root_manager)
+    return ScopedJavaLocalRef<jobject>();
+
+  JNIEnv* env = AttachCurrentThread();
+  return root_manager->java_ref().get(env);
+}
+
 bool RegisterBrowserAccessibilityManager(JNIEnv* env) {
   return RegisterNativesImpl(env);
 }
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.h b/content/browser/accessibility/browser_accessibility_manager_android.h
index 54af8ca1c..1336f76 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.h
+++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -218,6 +218,8 @@
               jint id,
               int direction);
 
+  JavaObjectWeakGlobalRef& java_ref() { return java_ref_; }
+
  protected:
   // AXTreeDelegate overrides.
   void OnAtomicUpdateFinished(
@@ -230,6 +232,8 @@
  private:
   BrowserAccessibilityAndroid* GetFromUniqueID(int32_t unique_id);
 
+   base::android::ScopedJavaLocalRef<jobject> GetJavaRefFromRootManager();
+
   // This gives BrowserAccessibilityManager::Create access to the class
   // constructor.
   friend class BrowserAccessibilityManager;
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index 7c2165cb..0b9c3d5 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -38,9 +38,7 @@
     BrowserAccessibilityDelegate* delegate,
     BrowserAccessibilityFactory* factory)
     : BrowserAccessibilityManager(delegate, factory),
-      tracked_scroll_object_(NULL),
-      focus_event_on_root_needed_(false),
-      inside_on_window_focused_(false) {
+      tracked_scroll_object_(NULL) {
   ui::win::CreateATLModuleIfNeeded();
   Initialize(initial_tree);
   ui::GetIAccessible2UsageObserverList().AddObserver(this);
@@ -119,32 +117,6 @@
   if (event == EVENT_OBJECT_REORDER && node->PlatformIsLeaf())
     return;
 
-  // Don't fire focus, or load complete notifications if the
-  // window isn't focused, because that can confuse screen readers into
-  // entering their "browse" mode.
-  if ((event == EVENT_OBJECT_FOCUS ||
-       event == IA2_EVENT_DOCUMENT_LOAD_COMPLETE) &&
-      !NativeViewHasFocus()) {
-    return;
-  }
-
-  // NVDA gets confused if we focus the main document element when it hasn't
-  // finished loading and it has no children at all, so suppress that event.
-  if (event == EVENT_OBJECT_FOCUS &&
-      node == GetRoot() &&
-      node->PlatformChildCount() == 0 &&
-      !node->HasState(ui::AX_STATE_BUSY) &&
-      !node->manager()->GetTreeData().loaded) {
-    return;
-  }
-
-  // If a focus event is needed on the root, fire that first before
-  // this event.
-  if (event == EVENT_OBJECT_FOCUS && node == GetRoot())
-    focus_event_on_root_needed_ = false;
-  else if (focus_event_on_root_needed_)
-    OnWindowFocused();
-
   // Pass the negation of this node's unique id in the |child_id|
   // argument to NotifyWinEvent; the AT client will then call get_accChild
   // on the HWND's accessibility object and pass it that same id, which
@@ -157,34 +129,6 @@
   BrowserAccessibilityStateImpl::GetInstance()->OnScreenReaderDetected();
 }
 
-void BrowserAccessibilityManagerWin::OnWindowFocused() {
-  // Make sure we don't call this recursively.
-  if (inside_on_window_focused_)
-    return;
-  inside_on_window_focused_ = true;
-
-  // This is called either when this web frame gets focused, or when
-  // the root of the accessibility tree changes. In both cases, we need
-  // to fire a focus event on the root and then on the focused element
-  // within the page, if different.
-
-  // Set this flag so that we'll keep trying to fire these focus events
-  // if they're not successful this time.
-  focus_event_on_root_needed_ = true;
-
-  if (!NativeViewHasFocus()) {
-    inside_on_window_focused_ = false;
-    return;
-  }
-
-  // Try to fire a focus event on the root first and then the focused node.
-  // This will clear focus_event_on_root_needed_ if successful.
-  if (GetFocus() != GetRoot() && GetRoot())
-    NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetRoot());
-  BrowserAccessibilityManager::OnWindowFocused();
-  inside_on_window_focused_ = false;
-}
-
 void BrowserAccessibilityManagerWin::UserIsReloading() {
   if (GetRoot())
     MaybeCallNotifyWinEvent(IA2_EVENT_DOCUMENT_RELOAD, GetRoot());
@@ -219,23 +163,6 @@
     return;
   }
 
-  // NVDA gets confused if we focus the main document element when it hasn't
-  // finished loading and it has no children at all, so suppress that event.
-  if (event_type == ui::AX_EVENT_FOCUS &&
-      node == GetRoot() &&
-      node->PlatformChildCount() == 0 &&
-      !node->HasState(ui::AX_STATE_BUSY) &&
-      !node->manager()->GetTreeData().loaded) {
-    return;
-  }
-
-  // If a focus event is needed on the root, fire that first before
-  // this event.
-  if (event_type == ui::AX_EVENT_FOCUS && node == GetRoot())
-    focus_event_on_root_needed_ = false;
-  else if (focus_event_on_root_needed_)
-    OnWindowFocused();
-
   LONG event_id = EVENT_MIN;
   switch (event_type) {
     case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
@@ -310,6 +237,26 @@
   }
 }
 
+bool BrowserAccessibilityManagerWin::CanFireEvents() {
+  BrowserAccessibilityDelegate* root_delegate = GetDelegateFromRootManager();
+  if (!root_delegate)
+    return false;
+  HWND hwnd = root_delegate->AccessibilityGetAcceleratedWidget();
+  return hwnd != nullptr;
+}
+
+void BrowserAccessibilityManagerWin::FireFocusEvent(
+    BrowserAccessibility* node) {
+  // On Windows, we always fire a FOCUS event on the root of a frame before
+  // firing a focus event within that frame.
+  if (node->manager() != last_focused_manager_ &&
+      node != node->manager()->GetRoot()) {
+    NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, node->manager()->GetRoot());
+  }
+
+  BrowserAccessibilityManager::FireFocusEvent(node);
+}
+
 void BrowserAccessibilityManagerWin::OnNodeCreated(ui::AXTree* tree,
                                                    ui::AXNode* node) {
   DCHECK(node);
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h
index be0b5d9..42c7da8 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.h
+++ b/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -43,10 +43,11 @@
   void OnIAccessible2Used() override;
 
   // BrowserAccessibilityManager methods
-  void OnWindowFocused() override;
   void UserIsReloading() override;
   void NotifyAccessibilityEvent(
       ui::AXEvent event_type, BrowserAccessibility* node) override;
+  bool CanFireEvents() override;
+  void FireFocusEvent(BrowserAccessibility* node) override;
 
   // Track this object and post a VISIBLE_DATA_CHANGED notification when
   // its container scrolls.
@@ -74,14 +75,6 @@
   // TODO(dmazzoni): remove once http://crbug.com/113483 is fixed.
   BrowserAccessibilityWin* tracked_scroll_object_;
 
-  // Set to true if we need to fire a focus event on the root as soon as
-  // possible.
-  bool focus_event_on_root_needed_;
-
-  // A flag to keep track of if we're inside the OnWindowFocused call stack
-  // so we don't keep calling it recursively.
-  bool inside_on_window_focused_;
-
   DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManagerWin);
 };
 
diff --git a/content/browser/android/synchronous_compositor_base.cc b/content/browser/android/synchronous_compositor_base.cc
index 1ef5e86..39d8b24 100644
--- a/content/browser/android/synchronous_compositor_base.cc
+++ b/content/browser/android/synchronous_compositor_base.cc
@@ -25,10 +25,10 @@
     g_gpu_service = LAZY_INSTANCE_INITIALIZER;
 
 base::Thread* CreateInProcessGpuThreadForSynchronousCompositor(
-    const InProcessChildThreadParams& params) {
+    const InProcessChildThreadParams& params,
+    const gpu::GpuPreferences& gpu_preferences) {
   DCHECK(g_gpu_service.Get());
-  return new InProcessGpuThread(params,
-                                g_gpu_service.Get()->gpu_preferences(),
+  return new InProcessGpuThread(params, gpu_preferences,
                                 g_gpu_service.Get()->sync_point_manager());
 }
 
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc
index ceb5985..90e3a726 100644
--- a/content/browser/frame_host/frame_tree.cc
+++ b/content/browser/frame_host/frame_tree.cc
@@ -327,6 +327,11 @@
 
   focused_frame_tree_node_id_ = node->frame_tree_node_id();
   node->DidFocus();
+
+  // The accessibility tree data for the root of the frame tree keeps
+  // track of the focused frame too, so update that every time the
+  // focused frame changes.
+  root()->current_frame_host()->UpdateAXTreeData();
 }
 
 void FrameTree::SetFrameRemoveListener(
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 3b619f15..705ab3a 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1630,8 +1630,8 @@
       detail.ax_tree_id = GetAXTreeID();
       if (param.update.has_tree_data) {
         detail.update.has_tree_data = true;
-        AXContentTreeDataToAXTreeData(param.update.tree_data,
-                                      &detail.update.tree_data);
+        ax_content_tree_data_ = param.update.tree_data;
+        AXContentTreeDataToAXTreeData(&detail.update.tree_data);
       }
       detail.update.node_id_to_clear = param.update.node_id_to_clear;
       detail.update.nodes.resize(param.update.nodes.size());
@@ -1724,8 +1724,8 @@
                                     &dst_snapshot.nodes[i]);
     }
     if (snapshot.has_tree_data) {
-      AXContentTreeDataToAXTreeData(snapshot.tree_data,
-                                    &dst_snapshot.tree_data);
+      ax_content_tree_data_ = snapshot.tree_data;
+      AXContentTreeDataToAXTreeData(&dst_snapshot.tree_data);
       dst_snapshot.has_tree_data = true;
     }
     it->second.Run(dst_snapshot);
@@ -2343,6 +2343,27 @@
   accessibility_testing_callback_ = callback;
 }
 
+void RenderFrameHostImpl::UpdateAXTreeData() {
+  AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode();
+  if (accessibility_mode == AccessibilityModeOff ||
+      !RenderFrameHostImpl::IsRFHStateActive(rfh_state())) {
+    return;
+  }
+
+  std::vector<AXEventNotificationDetails> details;
+  details.reserve(1U);
+  AXEventNotificationDetails detail;
+  detail.ax_tree_id = GetAXTreeID();
+  detail.update.has_tree_data = true;
+  AXContentTreeDataToAXTreeData(&detail.update.tree_data);
+  details.push_back(detail);
+
+  if (browser_accessibility_manager_)
+    browser_accessibility_manager_->OnAccessibilityEvents(details);
+
+  delegate_->AccessibilityEventReceived(details);
+}
+
 void RenderFrameHostImpl::SetTextTrackSettings(
     const FrameMsg_TextTrackSettings_Params& params) {
   DCHECK(!GetParent());
@@ -2625,8 +2646,9 @@
 }
 
 void RenderFrameHostImpl::AXContentTreeDataToAXTreeData(
-    const AXContentTreeData& src,
     ui::AXTreeData* dst) {
+  const AXContentTreeData& src = ax_content_tree_data_;
+
   // Copy the common fields.
   *dst = src;
 
@@ -2635,6 +2657,19 @@
 
   if (src.parent_routing_id != -1)
     dst->parent_tree_id = RoutingIDToAXTreeID(src.parent_routing_id);
+
+  // If this is not the root frame tree node, we're done.
+  if (frame_tree_node()->parent())
+    return;
+
+  // For the root frame tree node, also store the AXTreeID of the focused frame.
+  FrameTreeNode* focused_frame_tree_node = frame_tree_->GetFocusedFrame();
+  if (!focused_frame_tree_node)
+    return;
+  RenderFrameHostImpl* focused_frame =
+      focused_frame_tree_node->current_frame_host();
+  DCHECK(focused_frame);
+  dst->focused_tree_id = focused_frame->GetAXTreeID();
 }
 
 }  // 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 bf8bac3..c8bfa7b 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -467,6 +467,11 @@
   void SetAccessibilityCallbackForTesting(
       const base::Callback<void(ui::AXEvent, int)>& callback);
 
+  // Called when the metadata about the accessibility tree for this frame
+  // changes due to a browser-side change, as opposed to due to an IPC from
+  // a renderer.
+  void UpdateAXTreeData();
+
   // Send a message to the render process to change text track style settings.
   void SetTextTrackSettings(const FrameMsg_TextTrackSettings_Params& params);
 
@@ -707,8 +712,7 @@
 
   // Convert the content-layer-specific AXContentTreeData to a general-purpose
   // AXTreeData structure.
-  void AXContentTreeDataToAXTreeData(const AXContentTreeData& src,
-                                     ui::AXTreeData* dst);
+  void AXContentTreeDataToAXTreeData(ui::AXTreeData* dst);
 
   // Returns the RenderWidgetHostView used for accessibility. For subframes,
   // this function will return the platform view on the main frame; for main
@@ -881,6 +885,9 @@
   // we don't keep trying to reset forever.
   int accessibility_reset_count_;
 
+  // The last AXContentTreeData for this frame received from the RenderFrame.
+  AXContentTreeData ax_content_tree_data_;
+
   // The mapping from callback id to corresponding callback for pending
   // accessibility tree snapshot calls created by RequestAXTreeSnapshot.
   std::map<int, AXTreeSnapshotCallback> ax_tree_snapshot_callbacks_;
diff --git a/content/browser/geolocation/network_location_request.h b/content/browser/geolocation/network_location_request.h
index d87b373..6f7673a 100644
--- a/content/browser/geolocation/network_location_request.h
+++ b/content/browser/geolocation/network_location_request.h
@@ -5,9 +5,11 @@
 #ifndef CONTENT_BROWSER_GEOLOCATION_NETWORK_LOCATION_REQUEST_H_
 #define CONTENT_BROWSER_GEOLOCATION_NETWORK_LOCATION_REQUEST_H_
 
+#include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/strings/string16.h"
 #include "content/browser/geolocation/wifi_data_provider.h"
 #include "content/common/content_export.h"
 #include "net/url_request/url_fetcher_delegate.h"
diff --git a/content/browser/geolocation/wifi_data_provider.cc b/content/browser/geolocation/wifi_data_provider.cc
index 71b78c4765..433572c 100644
--- a/content/browser/geolocation/wifi_data_provider.cc
+++ b/content/browser/geolocation/wifi_data_provider.cc
@@ -4,11 +4,16 @@
 
 #include "content/browser/geolocation/wifi_data_provider.h"
 
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/location.h"
+#include "base/thread_task_runner_handle.h"
+
 namespace content {
 
 WifiDataProvider::WifiDataProvider()
-    : client_loop_(base::MessageLoop::current()) {
-  DCHECK(client_loop_);
+    : client_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
+  DCHECK(client_task_runner_);
 }
 
 WifiDataProvider::~WifiDataProvider() {
@@ -27,16 +32,12 @@
 }
 
 void WifiDataProvider::RunCallbacks() {
-  client_loop_->task_runner()->PostTask(
+  client_task_runner_->PostTask(
       FROM_HERE, base::Bind(&WifiDataProvider::DoRunCallbacks, this));
 }
 
 bool WifiDataProvider::CalledOnClientThread() const {
-  return base::MessageLoop::current() == this->client_loop_;
-}
-
-base::MessageLoop* WifiDataProvider::client_loop() const {
-  return client_loop_;
+  return client_task_runner()->BelongsToCurrentThread();
 }
 
 void WifiDataProvider::DoRunCallbacks() {
diff --git a/content/browser/geolocation/wifi_data_provider.h b/content/browser/geolocation/wifi_data_provider.h
index 96ab881..ce514969 100644
--- a/content/browser/geolocation/wifi_data_provider.h
+++ b/content/browser/geolocation/wifi_data_provider.h
@@ -7,13 +7,10 @@
 
 #include <set>
 
-#include "base/bind.h"
-#include "base/callback.h"
+#include "base/callback_forward.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_util.h"
+#include "base/single_thread_task_runner.h"
 #include "content/browser/geolocation/wifi_data.h"
 #include "content/common/content_export.h"
 
@@ -57,14 +54,15 @@
 
   bool CalledOnClientThread() const;
 
-  base::MessageLoop* client_loop() const;
+  scoped_refptr<base::SingleThreadTaskRunner> client_task_runner() const {
+    return client_task_runner_;
+  }
 
  private:
   void DoRunCallbacks();
 
-  // Reference to the client's message loop. All callbacks should happen in this
-  // context.
-  base::MessageLoop* client_loop_;
+  // The task runner for the client thread, all callbacks should run on it.
+  scoped_refptr<base::SingleThreadTaskRunner> client_task_runner_;
 
   CallbackSet callbacks_;
 
diff --git a/content/browser/geolocation/wifi_data_provider_chromeos.cc b/content/browser/geolocation/wifi_data_provider_chromeos.cc
index 02757ae0..4f148667 100644
--- a/content/browser/geolocation/wifi_data_provider_chromeos.cc
+++ b/content/browser/geolocation/wifi_data_provider_chromeos.cc
@@ -75,11 +75,11 @@
   WifiData new_data;
 
   if (GetAccessPointData(&new_data.access_point_data)) {
-    client_loop()->PostTask(
+    client_task_runner()->PostTask(
         FROM_HERE,
         base::Bind(&WifiDataProviderChromeOs::DidWifiScanTask, this, new_data));
   } else {
-    client_loop()->PostTask(
+    client_task_runner()->PostTask(
         FROM_HERE,
         base::Bind(&WifiDataProviderChromeOs::DidWifiScanTaskNoResults, this));
   }
diff --git a/content/browser/geolocation/wifi_data_provider_chromeos.h b/content/browser/geolocation/wifi_data_provider_chromeos.h
index e901f01..c5055dc 100644
--- a/content/browser/geolocation/wifi_data_provider_chromeos.h
+++ b/content/browser/geolocation/wifi_data_provider_chromeos.h
@@ -7,6 +7,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
 #include "content/browser/geolocation/wifi_data_provider.h"
 #include "content/browser/geolocation/wifi_polling_policy.h"
 
diff --git a/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc b/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc
index a5d1744b..64bce2732 100644
--- a/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc
+++ b/content/browser/geolocation/wifi_data_provider_chromeos_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -10,6 +10,7 @@
 #include "chromeos/dbus/shill_manager_client.h"
 #include "chromeos/network/geolocation_handler.h"
 #include "content/browser/geolocation/wifi_data_provider_chromeos.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
@@ -27,7 +28,7 @@
         chromeos::DBusThreadManager::Get()->GetShillManagerClient();
     manager_test_ = manager_client_->GetTestInterface();
     provider_ = new WifiDataProviderChromeOs();
-    message_loop_.RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 
   void TearDown() override {
@@ -58,10 +59,10 @@
         manager_test_->AddGeoNetwork(shill::kTypeWifi, properties);
       }
     }
-    message_loop_.RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 
-  base::MessageLoopForUI message_loop_;
+  TestBrowserThreadBundle thread_bundle_;
   scoped_refptr<WifiDataProviderChromeOs> provider_;
   chromeos::ShillManagerClient* manager_client_;
   chromeos::ShillManagerClient::TestInterface* manager_test_;
@@ -69,17 +70,17 @@
 };
 
 TEST_F(GeolocationChromeOsWifiDataProviderTest, NoAccessPoints) {
-  message_loop_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Initial call to GetAccessPointData requests data and will return false.
   EXPECT_FALSE(GetAccessPointData());
-  message_loop_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Additional call to GetAccessPointData also returns false with no devices.
   EXPECT_FALSE(GetAccessPointData());
   EXPECT_EQ(0u, ap_data_.size());
 }
 
 TEST_F(GeolocationChromeOsWifiDataProviderTest, GetOneAccessPoint) {
-  message_loop_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(GetAccessPointData());
 
   AddAccessPoints(1, 1);
@@ -90,7 +91,7 @@
 }
 
 TEST_F(GeolocationChromeOsWifiDataProviderTest, GetManyAccessPoints) {
-  message_loop_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(GetAccessPointData());
 
   AddAccessPoints(3, 4);
diff --git a/content/browser/geolocation/wifi_data_provider_common.cc b/content/browser/geolocation/wifi_data_provider_common.cc
index 4406680c2..572455a 100644
--- a/content/browser/geolocation/wifi_data_provider_common.cc
+++ b/content/browser/geolocation/wifi_data_provider_common.cc
@@ -82,7 +82,7 @@
 }
 
 void WifiDataProviderCommon::ScheduleNextScan(int interval) {
-  client_loop()->task_runner()->PostDelayedTask(
+  client_task_runner()->PostDelayedTask(
       FROM_HERE, base::Bind(&WifiDataProviderCommon::DoWifiScanTask,
                             weak_factory_.GetWeakPtr()),
       base::TimeDelta::FromMilliseconds(interval));
diff --git a/content/browser/geolocation/wifi_data_provider_common_unittest.cc b/content/browser/geolocation/wifi_data_provider_common_unittest.cc
index b652170..8acf93a 100644
--- a/content/browser/geolocation/wifi_data_provider_common_unittest.cc
+++ b/content/browser/geolocation/wifi_data_provider_common_unittest.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <vector>
-
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/strings/string_util.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
-#include "build/build_config.h"
+#include "base/thread_task_runner_handle.h"
 #include "content/browser/geolocation/wifi_data_provider_common.h"
 #include "content/browser/geolocation/wifi_data_provider_manager.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -60,25 +60,6 @@
   virtual void UpdatePollingInterval(bool) {}
 };
 
-// Stops the specified (nested) message loop when the callback is called.
-class MessageLoopQuitter {
- public:
-  explicit MessageLoopQuitter(base::MessageLoop* message_loop)
-      : message_loop_to_quit_(message_loop),
-        callback_(base::Bind(&MessageLoopQuitter::OnWifiDataUpdate,
-                             base::Unretained(this))) {
-    CHECK(message_loop_to_quit_ != NULL);
-  }
-
-  void OnWifiDataUpdate() {
-    // Provider should call back on client's thread.
-    EXPECT_EQ(base::MessageLoop::current(), message_loop_to_quit_);
-    message_loop_to_quit_->QuitNow();
-  }
-  base::MessageLoop* message_loop_to_quit_;
-  WifiDataProviderManager::WifiDataUpdateCallback callback_;
-};
-
 class WifiDataProviderCommonWithMock : public WifiDataProviderCommon {
  public:
   WifiDataProviderCommonWithMock()
@@ -112,24 +93,40 @@
 class GeolocationWifiDataProviderCommonTest : public testing::Test {
  public:
   GeolocationWifiDataProviderCommonTest()
-      : loop_quitter_(&main_message_loop_) {
-  }
+      : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+        wifi_data_callback_(
+            base::Bind(&GeolocationWifiDataProviderCommonTest::OnWifiDataUpdate,
+                       base::Unretained(this))) {}
 
   void SetUp() override {
     provider_ = new WifiDataProviderCommonWithMock;
     wlan_api_ = provider_->new_wlan_api_.get();
     polling_policy_ = provider_->new_polling_policy_.get();
-    provider_->AddCallback(&loop_quitter_.callback_);
+    provider_->AddCallback(&wifi_data_callback_);
   }
+
   void TearDown() override {
-    provider_->RemoveCallback(&loop_quitter_.callback_);
+    provider_->RemoveCallback(&wifi_data_callback_);
     provider_->StopDataProvider();
     provider_ = NULL;
   }
 
+  void OnWifiDataUpdate() {
+    // Callbacks must run on the originating thread.
+    EXPECT_TRUE(main_task_runner_->BelongsToCurrentThread());
+    run_loop_->Quit();
+  }
+
+  void RunLoop() {
+    run_loop_.reset(new base::RunLoop());
+    run_loop_->Run();
+  }
+
  protected:
-  base::MessageLoop main_message_loop_;
-  MessageLoopQuitter loop_quitter_;
+  TestBrowserThreadBundle thread_bundle_;
+  scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+  scoped_ptr<base::RunLoop> run_loop_;
+  WifiDataProviderManager::WifiDataUpdateCallback wifi_data_callback_;
   scoped_refptr<WifiDataProviderCommonWithMock> provider_;
   MockWlanApi* wlan_api_;
   MockPollingPolicy* polling_policy_;
@@ -137,7 +134,7 @@
 
 TEST_F(GeolocationWifiDataProviderCommonTest, CreateDestroy) {
   // Test fixture members were SetUp correctly.
-  EXPECT_EQ(&main_message_loop_, base::MessageLoop::current());
+  EXPECT_TRUE(main_task_runner_->BelongsToCurrentThread());
   EXPECT_TRUE(NULL != provider_.get());
   EXPECT_TRUE(NULL != wlan_api_);
 }
@@ -148,20 +145,20 @@
   EXPECT_CALL(*polling_policy_, PollingInterval())
       .Times(AtLeast(1));
   provider_->StartDataProvider();
-  main_message_loop_.Run();
+  RunLoop();
   SUCCEED();
 }
 
-TEST_F(GeolocationWifiDataProviderCommonTest, NoWifi){
+TEST_F(GeolocationWifiDataProviderCommonTest, NoWifi) {
   EXPECT_CALL(*polling_policy_, NoWifiInterval())
       .Times(AtLeast(1));
   EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
       .WillRepeatedly(Return(false));
   provider_->StartDataProvider();
-  main_message_loop_.Run();
+  RunLoop();
 }
 
-TEST_F(GeolocationWifiDataProviderCommonTest, IntermittentWifi){
+TEST_F(GeolocationWifiDataProviderCommonTest, IntermittentWifi) {
   EXPECT_CALL(*polling_policy_, PollingInterval())
       .Times(AtLeast(1));
   EXPECT_CALL(*polling_policy_, NoWifiInterval())
@@ -180,8 +177,8 @@
   wlan_api_->data_out_.insert(single_access_point);
 
   provider_->StartDataProvider();
-  main_message_loop_.Run();
-  main_message_loop_.Run();
+  RunLoop();
+  RunLoop();
 }
 
 #if defined(OS_MACOSX)
@@ -195,7 +192,7 @@
   EXPECT_CALL(*polling_policy_, PollingInterval())
       .Times(AtLeast(1));
   provider_->StartDataProvider();
-  main_message_loop_.Run();
+  RunLoop();
   EXPECT_EQ(wlan_api_->calls_, 1);
   WifiData data;
   EXPECT_TRUE(provider_->GetData(&data));
@@ -221,7 +218,7 @@
   wlan_api_->data_out_.insert(single_access_point);
 
   provider_->StartDataProvider();
-  main_message_loop_.Run();
+  RunLoop();
   EXPECT_EQ(wlan_api_->calls_, 1);
   WifiData data;
   EXPECT_TRUE(provider_->GetData(&data));
@@ -230,12 +227,11 @@
 }
 
 TEST_F(GeolocationWifiDataProviderCommonTest, RegisterUnregister) {
-  MessageLoopQuitter loop_quitter(&main_message_loop_);
   WifiDataProviderManager::SetFactoryForTesting(
       CreateWifiDataProviderCommonWithMock);
-  WifiDataProviderManager::Register(&loop_quitter.callback_);
-  main_message_loop_.Run();
-  WifiDataProviderManager::Unregister(&loop_quitter.callback_);
+  WifiDataProviderManager::Register(&wifi_data_callback_);
+  RunLoop();
+  WifiDataProviderManager::Unregister(&wifi_data_callback_);
   WifiDataProviderManager::ResetFactoryForTesting();
 }
 
diff --git a/content/browser/geolocation/wifi_data_provider_linux_unittest.cc b/content/browser/geolocation/wifi_data_provider_linux_unittest.cc
index 3ca35d1..7f36a2c 100644
--- a/content/browser/geolocation/wifi_data_provider_linux_unittest.cc
+++ b/content/browser/geolocation/wifi_data_provider_linux_unittest.cc
@@ -9,8 +9,8 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "dbus/message.h"
 #include "dbus/mock_bus.h"
 #include "dbus/mock_object_proxy.h"
@@ -105,10 +105,9 @@
   }
 
  protected:
-  // DeviceDataProviderImplBase, a super class of WifiDataProviderLinux,
-  // requires a message loop to be present. message_loop_ is defined here,
-  // as it should outlive wifi_provider_linux_.
-  base::MessageLoop message_loop_;
+  // WifiDataProvider requires a task runner to be present. The |thread_bundle_|
+  // is defined here, as it should outlive |wifi_provider_linux_|.
+  TestBrowserThreadBundle thread_bundle_;
   scoped_refptr<dbus::MockBus> mock_bus_;
   scoped_refptr<dbus::MockObjectProxy> mock_network_manager_proxy_;
   scoped_refptr<dbus::MockObjectProxy> mock_access_point_proxy_;
diff --git a/content/browser/geolocation/wifi_data_provider_manager.h b/content/browser/geolocation/wifi_data_provider_manager.h
index bb2af81e..652cf64 100644
--- a/content/browser/geolocation/wifi_data_provider_manager.h
+++ b/content/browser/geolocation/wifi_data_provider_manager.h
@@ -21,7 +21,6 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_util.h"
 #include "content/browser/geolocation/wifi_data.h"
diff --git a/content/browser/geolocation/wifi_data_provider_win_unittest.cc b/content/browser/geolocation/wifi_data_provider_win_unittest.cc
index cb3c21ce..d256a4a3 100644
--- a/content/browser/geolocation/wifi_data_provider_win_unittest.cc
+++ b/content/browser/geolocation/wifi_data_provider_win_unittest.cc
@@ -6,13 +6,14 @@
 // WifiDataProviderCommon and covered by it's unit tests.
 
 #include "content/browser/geolocation/wifi_data_provider_win.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
 
 TEST(GeolocationWifiDataProviderWinTest, CreateDestroy) {
-  // WifiDataProviderCommon requires the client to have a message loop.
-  base::MessageLoop dummy_loop;
+  // WifiDataProvider requires a task runner to be present.
+  TestBrowserThreadBundle thread_bundle;
   scoped_refptr<WifiDataProviderWin> instance(new WifiDataProviderWin);
   instance = NULL;
   SUCCEED();
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 3433b55..9bcbdd2 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -36,6 +36,7 @@
 #include "content/common/view_messages.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/gpu_utils.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/render_widget_host_view_frame_subscriber.h"
@@ -44,6 +45,7 @@
 #include "content/public/common/result_codes.h"
 #include "content/public/common/sandbox_type.h"
 #include "content/public/common/sandboxed_process_launcher_delegate.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
 #include "ipc/ipc_channel_handle.h"
 #include "ipc/ipc_switches.h"
@@ -105,13 +107,13 @@
 #endif
   switches::kEnableHeapProfiling,
   switches::kEnableLogging,
-  switches::kEnableShareGroupAsyncTextureUpload,
 #if defined(OS_ANDROID)
   switches::kEnableUnifiedMediaPipeline,
 #endif
 #if defined(OS_CHROMEOS)
   switches::kDisableVaapiAcceleratedVideoEncode,
 #endif
+  switches::kGpuDriverBugWorkarounds,
   switches::kGpuStartupDialog,
   switches::kGpuSandboxAllowSysVShm,
   switches::kGpuSandboxFailuresFatal,
@@ -134,9 +136,6 @@
   switches::kEnableSandboxLogging,
   switches::kShowMacOverlayBorders,
 #endif
-#if defined(USE_AURA)
-  switches::kUIPrioritizeInGpuProcess,
-#endif
 #if defined(USE_OZONE)
   switches::kOzonePlatform,
 #endif
@@ -546,7 +545,8 @@
     DCHECK(g_gpu_main_thread_factory);
     in_process_gpu_thread_.reset(
         g_gpu_main_thread_factory(InProcessChildThreadParams(
-            channel_id, base::MessageLoop::current()->task_runner())));
+            channel_id, base::MessageLoop::current()->task_runner()),
+            GetGpuPreferencesFromCommandLine()));
     base::Thread::Options options;
 #if defined(OS_WIN)
     // WGL needs to create its own window and pump messages on it.
@@ -562,7 +562,7 @@
     return false;
   }
 
-  if (!Send(new GpuMsg_Initialize()))
+  if (!Send(new GpuMsg_Initialize(GetGpuPreferencesFromCommandLine())))
     return false;
 
   return true;
@@ -982,13 +982,13 @@
   if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED)
     cmd_line->AppendSwitch(switches::kDisableGpuSandbox);
 
+  // TODO(penghuang): Replace all GPU related switches with GpuPreferences.
+  // https://crbug.com/590825
   // If you want a browser command-line switch passed to the GPU process
   // you need to add it to |kSwitchNames| at the beginning of this file.
   cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
                              arraysize(kSwitchNames));
   cmd_line->CopySwitchesFrom(
-      browser_command_line, switches::kGpuSwitches, switches::kNumGpuSwitches);
-  cmd_line->CopySwitchesFrom(
       browser_command_line, switches::kGLSwitchesCopiedFromGpuProcessHost,
       switches::kGLSwitchesCopiedFromGpuProcessHostNumSwitches);
 
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h
index b3f6419a..90703a7 100644
--- a/content/browser/gpu/gpu_process_host.h
+++ b/content/browser/gpu/gpu_process_host.h
@@ -40,6 +40,7 @@
 }
 
 namespace gpu {
+struct GpuPreferences;
 struct SyncToken;
 }
 
@@ -52,7 +53,7 @@
 class ShaderDiskCache;
 
 typedef base::Thread* (*GpuMainThreadFactoryFunction)(
-    const InProcessChildThreadParams&);
+    const InProcessChildThreadParams&, const gpu::GpuPreferences&);
 
 class GpuProcessHost : public BrowserChildProcessHostDelegate,
                        public IPC::Sender,
diff --git a/content/browser/mojo/chrome_renderer_manifest.json b/content/browser/mojo/chrome_renderer_manifest.json
index 7022695..463be6d2 100644
--- a/content/browser/mojo/chrome_renderer_manifest.json
+++ b/content/browser/mojo/chrome_renderer_manifest.json
@@ -1,5 +1,5 @@
 {
   "name": "exe:chrome_renderer",
   "display_name": "Chrome Renderer",
-  "capabilities": { "mojo:mus": [ "mus.mojom.Gpu" ] }
+  "capabilities": { "mojo:mus": [ "mus::mojom::Gpu" ] }
 }
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 b50408e..df811e6 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1608,19 +1608,12 @@
 BrowserAccessibilityManager*
     RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManager(
         BrowserAccessibilityDelegate* delegate) {
-  // TODO(dmazzoni): Currently there can only be one
-  // BrowserAccessibilityManager per ContentViewCore, so return NULL
-  // if there's already a BrowserAccessibilityManager for the main
-  // frame.  Eventually, in order to support cross-process iframes on
-  // Android we'll need to add support for a
-  // BrowserAccessibilityManager for a child frame.
-  // http://crbug.com/423846
-  if (!host_ || host_->GetRootBrowserAccessibilityManager())
-    return NULL;
-
   base::android::ScopedJavaLocalRef<jobject> obj;
-  if (content_view_core_)
+  if (host_ &&
+      host_->GetRootBrowserAccessibilityManager() &&
+      content_view_core_) {
     obj = content_view_core_->GetJavaObject();
+  }
   return new BrowserAccessibilityManagerAndroid(
       obj,
       BrowserAccessibilityManagerAndroid::GetEmptyDocument(),
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index 85d9830..1dafcef0 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -130,6 +130,29 @@
       base::Bind(&ServiceWorkerContextWrapper::ShutdownOnIO, this));
 }
 
+void ServiceWorkerContextWrapper::InitializeResourceContext(
+    ResourceContext* resource_context,
+    scoped_refptr<net::URLRequestContextGetter> request_context_getter) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  resource_context_ = resource_context;
+  request_context_getter_ = request_context_getter;
+  // Can be null in tests.
+  if (request_context_getter_)
+    request_context_getter_->AddObserver(this);
+}
+
+void ServiceWorkerContextWrapper::OnContextShuttingDown() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  request_context_getter_->RemoveObserver(this);
+
+  // OnContextShuttingDown is called when the ProfileIOData (ResourceContext) is
+  // shutting down, so call ShutdownOnIO() to clear resource_context_.
+  // This doesn't seem to be called when using content_shell, so we still must
+  // also call ShutdownOnIO() in Shutdown(), which is called when the storage
+  // partition is destroyed.
+  ShutdownOnIO();
+}
+
 void ServiceWorkerContextWrapper::DeleteAndStartOver() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (!context_core_) {
@@ -158,12 +181,6 @@
   return resource_context_;
 }
 
-void ServiceWorkerContextWrapper::set_resource_context(
-    ResourceContext* resource_context) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  resource_context_ = resource_context;
-}
-
 static void FinishRegistrationOnIO(
     const ServiceWorkerContext::ResultCallback& continuation,
     ServiceWorkerStatusCode status,
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h
index c99340c..5447d8e1 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include <string>
 #include <vector>
 
 #include "base/files/file_path.h"
@@ -16,6 +17,7 @@
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/service_worker_context.h"
+#include "net/url_request/url_request_context_getter_observer.h"
 
 namespace base {
 class FilePath;
@@ -42,6 +44,7 @@
 // is what is used internally in the service worker lib.
 class CONTENT_EXPORT ServiceWorkerContextWrapper
     : NON_EXPORTED_BASE(public ServiceWorkerContext),
+      public net::URLRequestContextGetterObserver,
       public base::RefCountedThreadSafe<ServiceWorkerContextWrapper> {
  public:
   using StatusCallback = base::Callback<void(ServiceWorkerStatusCode)>;
@@ -63,6 +66,14 @@
             storage::SpecialStoragePolicy* special_storage_policy);
   void Shutdown();
 
+  // Must be called on the IO thread.
+  void InitializeResourceContext(
+      ResourceContext* resource_context,
+      scoped_refptr<net::URLRequestContextGetter> request_context_getter);
+
+  // For net::URLRequestContextGetterObserver
+  void OnContextShuttingDown() override;
+
   // Deletes all files on disk and restarts the system asynchronously. This
   // leaves the system in a disabled state until it's done. This should be
   // called on the IO thread.
@@ -79,8 +90,6 @@
   // shutdown.
   ResourceContext* resource_context();
 
-  void set_resource_context(ResourceContext* resource_context);
-
   // The process manager can be used on either UI or IO.
   ServiceWorkerProcessManager* process_manager() {
     return process_manager_.get();
@@ -228,7 +237,7 @@
   const scoped_refptr<base::ObserverListThreadSafe<
       ServiceWorkerContextObserver>> observer_list_;
   const scoped_ptr<ServiceWorkerProcessManager> process_manager_;
-  // Cleared in Shutdown():
+  // Cleared in ShutdownOnIO():
   scoped_ptr<ServiceWorkerContextCore> context_core_;
 
   // Initialized in Init(); true if the user data directory is empty.
@@ -240,6 +249,8 @@
   // The ResourceContext associated with this context.
   ResourceContext* resource_context_;
 
+  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
+
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContextWrapper);
 };
 
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc
index 75c257a..7a0dd9c9 100644
--- a/content/browser/storage_partition_impl_map.cc
+++ b/content/browser/storage_partition_impl_map.cc
@@ -609,9 +609,10 @@
 
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
-        base::Bind(&ServiceWorkerContextWrapper::set_resource_context,
+        base::Bind(&ServiceWorkerContextWrapper::InitializeResourceContext,
                    partition->GetServiceWorkerContext(),
-                   browser_context_->GetResourceContext()));
+                   browser_context_->GetResourceContext(),
+                   make_scoped_refptr(partition->GetURLRequestContext())));
 
     // We do not call InitializeURLRequestContext() for media contexts because,
     // other than the HTTP cache, the media contexts share the same backing
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 24e42fd..ab31fe7a 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -467,6 +467,15 @@
   return net::IsPortAllowedForScheme(gurl.EffectiveIntPort(), gurl.scheme());
 }
 
+bool BlinkPlatformImpl::parseMultipartHeadersFromBody(
+    const char* bytes,
+    size_t size,
+    blink::WebURLResponse* response,
+    size_t* end) const {
+  return WebURLLoaderImpl::ParseMultipartHeadersFromBody(
+      bytes, size, response, end);
+}
+
 blink::WebThread* BlinkPlatformImpl::createThread(const char* name) {
   scoped_ptr<WebThreadImplForWorkerScheduler> thread(
       new WebThreadImplForWorkerScheduler(name));
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h
index bdf839e..ab81f26 100644
--- a/content/child/blink_platform_impl.h
+++ b/content/child/blink_platform_impl.h
@@ -96,6 +96,11 @@
   blink::WebURLError cancelledError(const blink::WebURL& url) const override;
   bool isReservedIPAddress(const blink::WebString& host) const override;
   bool portAllowed(const blink::WebURL& url) const override;
+  bool parseMultipartHeadersFromBody(const char* bytes,
+                                     size_t size,
+                                     blink::WebURLResponse* response,
+                                     size_t* end) const override;
+
   blink::WebThread* createThread(const char* name) override;
   blink::WebThread* currentThread() override;
   void recordAction(const blink::UserMetricsAction&) override;
diff --git a/content/child/v8_value_converter_impl_unittest.cc b/content/child/v8_value_converter_impl_unittest.cc
index 435ea30..311fa7f4 100644
--- a/content/child/v8_value_converter_impl_unittest.cc
+++ b/content/child/v8_value_converter_impl_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/values.h"
 #include "content/child/v8_value_converter_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 namespace content {
@@ -288,7 +287,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   // Set up objects to throw when reading or writing 'foo'.
   const char* source =
@@ -331,7 +329,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "var arr = [];"
@@ -408,7 +405,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "Object.prototype.foo = 'foo';"
@@ -433,7 +429,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "return { foo: undefined, bar: null };"
@@ -492,7 +487,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "return {"
@@ -531,7 +525,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "var a = [0];"
@@ -556,7 +549,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   v8::Local<v8::Object> object;
   {
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc
index 88018f9b..b4c4f69 100644
--- a/content/child/web_url_loader_impl.cc
+++ b/content/child/web_url_loader_impl.cc
@@ -83,6 +83,17 @@
 
 namespace {
 
+// The list of response headers that we do not copy from the original
+// response when generating a WebURLResponse for a MIME payload.
+const char* const kReplaceHeaders[] = {
+  "content-type",
+  "content-length",
+  "content-disposition",
+  "content-range",
+  "range",
+  "set-cookie"
+};
+
 using HeadersVector = ResourceDevToolsInfo::HeadersVector;
 
 // Converts timing data from |load_timing| to the format used by WebKit.
@@ -1143,4 +1154,52 @@
   context_->SetWebTaskRunner(make_scoped_ptr(loading_task_runner->clone()));
 }
 
+// This function is implemented here because it uses net functions. it is
+// tested in
+// third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp.
+bool WebURLLoaderImpl::ParseMultipartHeadersFromBody(
+    const char* bytes,
+    size_t size,
+    blink::WebURLResponse* response,
+    size_t* end) {
+  int headers_end_pos =
+      net::HttpUtil::LocateEndOfAdditionalHeaders(bytes, size, 0);
+
+  if (headers_end_pos < 0)
+    return false;
+
+  *end = headers_end_pos;
+  // Eat headers and prepend a status line as is required by
+  // HttpResponseHeaders.
+  std::string headers("HTTP/1.1 200 OK\r\n");
+  headers.append(bytes, headers_end_pos);
+
+  scoped_refptr<net::HttpResponseHeaders> response_headers =
+      new net::HttpResponseHeaders(
+          net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
+
+  std::string mime_type;
+  response_headers->GetMimeType(&mime_type);
+  response->setMIMEType(WebString::fromUTF8(mime_type));
+
+  std::string charset;
+  response_headers->GetCharset(&charset);
+  response->setTextEncodingName(WebString::fromUTF8(charset));
+
+  // Copy headers listed in kReplaceHeaders to the response.
+  for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) {
+    std::string name(kReplaceHeaders[i]);
+    std::string value;
+    WebString webStringName(WebString::fromLatin1(name));
+    size_t iterator = 0;
+
+    response->clearHTTPHeaderField(webStringName);
+    while (response_headers->EnumerateHeader(&iterator, name, &value)) {
+      response->addHTTPHeaderField(webStringName,
+                                   WebString::fromLatin1(value));
+    }
+  }
+  return true;
+}
+
 }  // namespace content
diff --git a/content/child/web_url_loader_impl.h b/content/child/web_url_loader_impl.h
index 019108a..804d1b0 100644
--- a/content/child/web_url_loader_impl.h
+++ b/content/child/web_url_loader_impl.h
@@ -68,6 +68,12 @@
                          int intra_priority_value) override;
   void setLoadingTaskRunner(blink::WebTaskRunner* loading_task_runner) override;
 
+  // This is a utility function for multipart image resources.
+  static bool ParseMultipartHeadersFromBody(const char* bytes,
+                                            size_t size,
+                                            blink::WebURLResponse* response,
+                                            size_t* end);
+
  private:
   class Context;
   class RequestPeerImpl;
diff --git a/content/common/accessibility_messages.h b/content/common/accessibility_messages.h
index 660484c..b1a9bc82 100644
--- a/content/common/accessibility_messages.h
+++ b/content/common/accessibility_messages.h
@@ -42,6 +42,7 @@
 IPC_STRUCT_TRAITS_BEGIN(content::AXContentTreeData)
   IPC_STRUCT_TRAITS_MEMBER(tree_id)
   IPC_STRUCT_TRAITS_MEMBER(parent_tree_id)
+  IPC_STRUCT_TRAITS_MEMBER(focused_tree_id)
   IPC_STRUCT_TRAITS_MEMBER(url)
   IPC_STRUCT_TRAITS_MEMBER(title)
   IPC_STRUCT_TRAITS_MEMBER(mimetype)
diff --git a/content/common/gpu/gpu_host_messages.h b/content/common/gpu/gpu_host_messages.h
index 1428c8a..7ba30f4 100644
--- a/content/common/gpu/gpu_host_messages.h
+++ b/content/common/gpu/gpu_host_messages.h
@@ -14,6 +14,7 @@
 #include "content/public/common/common_param_traits.h"
 #include "gpu/command_buffer/common/sync_token.h"
 #include "gpu/command_buffer/common/value_state.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
 #include "gpu/config/gpu_info.h"
 #include "gpu/ipc/common/memory_stats.h"
 #include "ipc/ipc_channel_handle.h"
@@ -100,6 +101,33 @@
 IPC_STRUCT_TRAITS_END()
 #endif
 
+IPC_STRUCT_TRAITS_BEGIN(gpu::GpuPreferences)
+  IPC_STRUCT_TRAITS_MEMBER(single_process)
+  IPC_STRUCT_TRAITS_MEMBER(in_process_gpu)
+  IPC_STRUCT_TRAITS_MEMBER(ui_prioritize_in_gpu_process)
+  IPC_STRUCT_TRAITS_MEMBER(compile_shader_always_succeeds)
+  IPC_STRUCT_TRAITS_MEMBER(disable_gl_error_limit)
+  IPC_STRUCT_TRAITS_MEMBER(disable_glsl_translator)
+  IPC_STRUCT_TRAITS_MEMBER(disable_gpu_driver_bug_workarounds)
+  IPC_STRUCT_TRAITS_MEMBER(disable_shader_name_hashing)
+  IPC_STRUCT_TRAITS_MEMBER(enable_gpu_command_logging)
+  IPC_STRUCT_TRAITS_MEMBER(enable_gpu_debugging)
+  IPC_STRUCT_TRAITS_MEMBER(enable_gpu_service_logging_gpu)
+  IPC_STRUCT_TRAITS_MEMBER(disable_gpu_program_cache)
+  IPC_STRUCT_TRAITS_MEMBER(enforce_gl_minimums)
+  IPC_STRUCT_TRAITS_MEMBER(force_gpu_mem_available)
+  IPC_STRUCT_TRAITS_MEMBER(gpu_program_cache_size)
+  IPC_STRUCT_TRAITS_MEMBER(disable_gpu_shader_disk_cache)
+  IPC_STRUCT_TRAITS_MEMBER(enable_share_group_async_texture_upload)
+  IPC_STRUCT_TRAITS_MEMBER(enable_subscribe_uniform_extension)
+  IPC_STRUCT_TRAITS_MEMBER(enable_threaded_texture_mailboxes)
+  IPC_STRUCT_TRAITS_MEMBER(gl_shader_interm_output)
+  IPC_STRUCT_TRAITS_MEMBER(emulate_shader_precision)
+  IPC_STRUCT_TRAITS_MEMBER(enable_gpu_service_logging)
+  IPC_STRUCT_TRAITS_MEMBER(enable_gpu_service_tracing)
+  IPC_STRUCT_TRAITS_MEMBER(enable_unsafe_es3_apis)
+IPC_STRUCT_TRAITS_END()
+
 //------------------------------------------------------------------------------
 // GPU Messages
 // These are messages from the browser to the GPU process.
@@ -109,7 +137,8 @@
 // up between the browser and GPU process before doing any work that might
 // potentially crash the GPU process. Detection of the child process
 // exiting abruptly is predicated on having the IPC channel set up.
-IPC_MESSAGE_CONTROL0(GpuMsg_Initialize)
+IPC_MESSAGE_CONTROL1(GpuMsg_Initialize,
+                     gpu::GpuPreferences /* gpu_prefernces */)
 
 // Tells the GPU process to shutdown itself.
 IPC_MESSAGE_CONTROL0(GpuMsg_Finalize)
diff --git a/content/common/gpu/media/v4l2_image_processor.cc b/content/common/gpu/media/v4l2_image_processor.cc
index f0cf3977..340a1484 100644
--- a/content/common/gpu/media/v4l2_image_processor.cc
+++ b/content/common/gpu/media/v4l2_image_processor.cc
@@ -468,24 +468,22 @@
     }
   }
 
-  // TODO(posciak): Fix this to be non-Exynos specific.
-  // Exynos GSC is liable to race conditions if more than one output buffer is
-  // simultaneously enqueued, so enqueue just one.
-  if (output_buffer_queued_count_ == 0 && !free_output_buffers_.empty()) {
-    const int old_outputs_queued = output_buffer_queued_count_;
+  const int old_outputs_queued = output_buffer_queued_count_;
+  while (!free_output_buffers_.empty()) {
     if (!EnqueueOutputRecord())
       return;
-    if (old_outputs_queued == 0 && output_buffer_queued_count_ != 0) {
-      // We just started up a previously empty queue.
-      // Queue state changed; signal interrupt.
-      if (!device_->SetDevicePollInterrupt())
-        return;
-      // Start VIDIOC_STREAMON if we haven't yet.
-      if (!output_streamon_) {
-        __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-        IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
-        output_streamon_ = true;
-      }
+  }
+
+  if (old_outputs_queued == 0 && output_buffer_queued_count_ != 0) {
+    // We just started up a previously empty queue.
+    // Queue state changed; signal interrupt.
+    if (!device_->SetDevicePollInterrupt())
+      return;
+    // Start VIDIOC_STREAMON if we haven't yet.
+    if (!output_streamon_) {
+      __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+      IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
+      output_streamon_ = true;
     }
   }
   DCHECK_LE(output_buffer_queued_count_, 1);
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 4096ef2..3029054 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -187,6 +187,8 @@
       'public/browser/gpu_data_manager_observer.h',
       'public/browser/gpu_service_registry.cc',
       'public/browser/gpu_service_registry.h',
+      'public/browser/gpu_utils.cc',
+      'public/browser/gpu_utils.h',
       'public/browser/histogram_fetcher.h',
       'public/browser/host_zoom_map.h',
       'public/browser/indexed_db_context.h',
diff --git a/content/content_shell.gypi b/content/content_shell.gypi
index dd6fe7d..dff8369a 100644
--- a/content/content_shell.gypi
+++ b/content/content_shell.gypi
@@ -197,6 +197,8 @@
         'shell/browser/shell_web_contents_view_delegate_win.cc',
         'shell/common/layout_test/layout_test_messages.cc',
         'shell/common/layout_test/layout_test_messages.h',
+        'shell/common/layout_test/layout_test_switches.cc',
+        'shell/common/layout_test/layout_test_switches.h',
         'shell/common/leak_detection_result.h',
         'shell/common/shell_content_client.cc',
         'shell/common/shell_content_client.h',
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc
index 369cd4d..2452579 100644
--- a/content/gpu/gpu_child_thread.cc
+++ b/content/gpu/gpu_child_thread.cc
@@ -50,15 +50,6 @@
 static base::LazyInstance<scoped_refptr<ThreadSafeSender> >
     g_thread_safe_sender = LAZY_INSTANCE_INITIALIZER;
 
-bool GetSizeTFromSwitch(const base::CommandLine* command_line,
-                        const base::StringPiece& switch_string,
-                        size_t* value) {
-  if (!command_line->HasSwitch(switch_string))
-    return false;
-  std::string switch_value(command_line->GetSwitchValueASCII(switch_string));
-  return base::StringToSizeT(switch_value, value);
-}
-
 bool GpuProcessLogMessageHandler(int severity,
                                  const char* file, int line,
                                  size_t message_start,
@@ -162,7 +153,6 @@
     GpuMemoryBufferFactory* gpu_memory_buffer_factory,
     gpu::SyncPointManager* sync_point_manager)
     : ChildThreadImpl(GetOptions(gpu_memory_buffer_factory)),
-      gpu_preferences_(GetGpuPreferencesFromCommandLine()),
       dead_on_arrival_(dead_on_arrival),
       sync_point_manager_(sync_point_manager),
       gpu_info_(gpu_info),
@@ -357,7 +347,8 @@
   Send(new GpuHostMsg_CacheShader(client_id, key, shader));
 }
 
-void GpuChildThread::OnInitialize() {
+void GpuChildThread::OnInitialize(const gpu::GpuPreferences& gpu_preferences) {
+  gpu_preferences_ = gpu_preferences;
   // Record initialization only after collecting the GPU info because that can
   // take a significant amount of time.
   gpu_info_.initialization_time = base::Time::Now() - process_start_time_;
@@ -408,70 +399,6 @@
   }
 }
 
-// static
-gpu::GpuPreferences GpuChildThread::GetGpuPreferencesFromCommandLine() {
-  // TODO(penghuang): share below code with
-  // android_webview/browser/deferred_gpu_command_service.cc
-  // http://crbug.com/590825
-  // For any modification of below code, deferred_gpu_command_service.cc should
-  // be updated as well.
-  DCHECK(base::CommandLine::InitializedForCurrentProcess());
-  const base::CommandLine* command_line =
-      base::CommandLine::ForCurrentProcess();
-  gpu::GpuPreferences gpu_preferences;
-  gpu_preferences.single_process =
-      command_line->HasSwitch(switches::kSingleProcess);
-  gpu_preferences.in_process_gpu =
-      command_line->HasSwitch(switches::kInProcessGPU);
-  gpu_preferences.ui_prioritize_in_gpu_process =
-      command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess);
-  gpu_preferences.compile_shader_always_succeeds =
-      command_line->HasSwitch(switches::kCompileShaderAlwaysSucceeds);
-  gpu_preferences.disable_gl_error_limit =
-    command_line->HasSwitch(switches::kDisableGLErrorLimit);
-  gpu_preferences.disable_glsl_translator =
-    command_line->HasSwitch(switches::kDisableGLSLTranslator);
-  gpu_preferences.disable_gpu_driver_bug_workarounds =
-    command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds);
-  gpu_preferences.disable_shader_name_hashing =
-    command_line->HasSwitch(switches::kDisableShaderNameHashing);
-  gpu_preferences.enable_gpu_command_logging =
-    command_line->HasSwitch(switches::kEnableGPUCommandLogging);
-  gpu_preferences.enable_gpu_debugging =
-    command_line->HasSwitch(switches::kEnableGPUDebugging);
-  gpu_preferences.enable_gpu_service_logging_gpu =
-    command_line->HasSwitch(switches::kEnableGPUServiceLoggingGPU);
-  gpu_preferences.disable_gpu_program_cache =
-    command_line->HasSwitch(switches::kDisableGpuProgramCache);
-  gpu_preferences.enforce_gl_minimums =
-    command_line->HasSwitch(switches::kEnforceGLMinimums);
-  if (GetSizeTFromSwitch(command_line, switches::kForceGpuMemAvailableMb,
-                         &gpu_preferences.force_gpu_mem_available)) {
-    gpu_preferences.force_gpu_mem_available *= 1024 * 1024;
-  }
-  if (GetSizeTFromSwitch(command_line, switches::kGpuProgramCacheSizeKb,
-                         &gpu_preferences.gpu_program_cache_size)) {
-    gpu_preferences.gpu_program_cache_size *= 1024;
-  }
-  gpu_preferences.enable_share_group_async_texture_upload =
-    command_line->HasSwitch(switches::kEnableShareGroupAsyncTextureUpload);
-  gpu_preferences.enable_subscribe_uniform_extension =
-    command_line->HasSwitch(switches::kEnableSubscribeUniformExtension);
-  gpu_preferences.enable_threaded_texture_mailboxes =
-    command_line->HasSwitch(switches::kEnableThreadedTextureMailboxes);
-  gpu_preferences.gl_shader_interm_output =
-    command_line->HasSwitch(switches::kGLShaderIntermOutput);
-  gpu_preferences.emulate_shader_precision =
-    command_line->HasSwitch(switches::kEmulateShaderPrecision);
-  gpu_preferences.enable_gpu_service_logging =
-      command_line->HasSwitch(switches::kEnableGPUServiceLogging);
-  gpu_preferences.enable_gpu_service_tracing =
-      command_line->HasSwitch(switches::kEnableGPUServiceTracing);
-  gpu_preferences.enable_unsafe_es3_apis =
-    command_line->HasSwitch(switches::kEnableUnsafeES3APIs);
-  return gpu_preferences;
-}
-
 void GpuChildThread::OnCollectGraphicsInfo() {
 #if defined(OS_WIN)
   // GPU full info collection should only happen on un-sandboxed GPU process
diff --git a/content/gpu/gpu_child_thread.h b/content/gpu/gpu_child_thread.h
index ec7d19e..80a2412 100644
--- a/content/gpu/gpu_child_thread.h
+++ b/content/gpu/gpu_child_thread.h
@@ -71,8 +71,6 @@
   void Init(const base::Time& process_start_time);
   void StopWatchdog();
 
-  static gpu::GpuPreferences GetGpuPreferencesFromCommandLine();
-
  private:
   // ChildThread overrides.
   bool Send(IPC::Message* msg) override;
@@ -103,7 +101,7 @@
                          const std::string& shader) override;
 
   // Message handlers.
-  void OnInitialize();
+  void OnInitialize(const gpu::GpuPreferences& gpu_preferences);
   void OnFinalize();
   void OnCollectGraphicsInfo();
   void OnGetVideoMemoryUsageStats();
diff --git a/content/gpu/in_process_gpu_thread.cc b/content/gpu/in_process_gpu_thread.cc
index 1453ff2a..8f170c3 100644
--- a/content/gpu/in_process_gpu_thread.cc
+++ b/content/gpu/in_process_gpu_thread.cc
@@ -74,9 +74,10 @@
 }
 
 base::Thread* CreateInProcessGpuThread(
-    const InProcessChildThreadParams& params) {
+    const InProcessChildThreadParams& params,
+    const gpu::GpuPreferences& gpu_preferences) {
   return new InProcessGpuThread(
-      params, GpuChildThread::GetGpuPreferencesFromCommandLine(), nullptr);
+      params, gpu_preferences, nullptr);
 }
 
 }  // namespace content
diff --git a/content/gpu/in_process_gpu_thread.h b/content/gpu/in_process_gpu_thread.h
index 85b2c52..6124ba8 100644
--- a/content/gpu/in_process_gpu_thread.h
+++ b/content/gpu/in_process_gpu_thread.h
@@ -54,7 +54,8 @@
 };
 
 CONTENT_EXPORT base::Thread* CreateInProcessGpuThread(
-    const InProcessChildThreadParams& params);
+    const InProcessChildThreadParams& params,
+    const gpu::GpuPreferences& gpu_preferences);
 
 }  // namespace content
 
diff --git a/content/public/browser/gpu_utils.cc b/content/public/browser/gpu_utils.cc
new file mode 100644
index 0000000..773ee03
--- /dev/null
+++ b/content/public/browser/gpu_utils.cc
@@ -0,0 +1,89 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/gpu_utils.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "content/public/common/content_switches.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/config/gpu_switches.h"
+#include "ui/gl/gl_switches.h"
+
+namespace {
+
+bool GetUintFromSwitch(const base::CommandLine* command_line,
+                       const base::StringPiece& switch_string,
+                       uint32_t* value) {
+  if (!command_line->HasSwitch(switch_string))
+    return false;
+  std::string switch_value(command_line->GetSwitchValueASCII(switch_string));
+  return base::StringToUint(switch_value, value);
+}
+
+}  // namespace
+
+namespace content {
+
+const gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
+  DCHECK(base::CommandLine::InitializedForCurrentProcess());
+  const base::CommandLine* command_line =
+      base::CommandLine::ForCurrentProcess();
+  gpu::GpuPreferences gpu_preferences;
+  gpu_preferences.single_process =
+      command_line->HasSwitch(switches::kSingleProcess);
+  gpu_preferences.in_process_gpu =
+      command_line->HasSwitch(switches::kInProcessGPU);
+  gpu_preferences.ui_prioritize_in_gpu_process =
+      command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess);
+  gpu_preferences.compile_shader_always_succeeds =
+      command_line->HasSwitch(switches::kCompileShaderAlwaysSucceeds);
+  gpu_preferences.disable_gl_error_limit =
+      command_line->HasSwitch(switches::kDisableGLErrorLimit);
+  gpu_preferences.disable_glsl_translator =
+      command_line->HasSwitch(switches::kDisableGLSLTranslator);
+  gpu_preferences.disable_gpu_driver_bug_workarounds =
+      command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds);
+  gpu_preferences.disable_shader_name_hashing =
+      command_line->HasSwitch(switches::kDisableShaderNameHashing);
+  gpu_preferences.enable_gpu_command_logging =
+      command_line->HasSwitch(switches::kEnableGPUCommandLogging);
+  gpu_preferences.enable_gpu_debugging =
+      command_line->HasSwitch(switches::kEnableGPUDebugging);
+  gpu_preferences.enable_gpu_service_logging_gpu =
+      command_line->HasSwitch(switches::kEnableGPUServiceLoggingGPU);
+  gpu_preferences.disable_gpu_program_cache =
+      command_line->HasSwitch(switches::kDisableGpuProgramCache);
+  gpu_preferences.enforce_gl_minimums =
+      command_line->HasSwitch(switches::kEnforceGLMinimums);
+  if (GetUintFromSwitch(command_line, switches::kForceGpuMemAvailableMb,
+                        &gpu_preferences.force_gpu_mem_available)) {
+    gpu_preferences.force_gpu_mem_available *= 1024 * 1024;
+  }
+  if (GetUintFromSwitch(command_line, switches::kGpuProgramCacheSizeKb,
+                        &gpu_preferences.gpu_program_cache_size)) {
+    gpu_preferences.gpu_program_cache_size *= 1024;
+  }
+  gpu_preferences.disable_gpu_shader_disk_cache =
+      command_line->HasSwitch(switches::kDisableGpuShaderDiskCache);
+  gpu_preferences.enable_share_group_async_texture_upload =
+      command_line->HasSwitch(switches::kEnableShareGroupAsyncTextureUpload);
+  gpu_preferences.enable_subscribe_uniform_extension =
+      command_line->HasSwitch(switches::kEnableSubscribeUniformExtension);
+  gpu_preferences.enable_threaded_texture_mailboxes =
+      command_line->HasSwitch(switches::kEnableThreadedTextureMailboxes);
+  gpu_preferences.gl_shader_interm_output =
+      command_line->HasSwitch(switches::kGLShaderIntermOutput);
+  gpu_preferences.emulate_shader_precision =
+      command_line->HasSwitch(switches::kEmulateShaderPrecision);
+  gpu_preferences.enable_gpu_service_logging =
+      command_line->HasSwitch(switches::kEnableGPUServiceLogging);
+  gpu_preferences.enable_gpu_service_tracing =
+      command_line->HasSwitch(switches::kEnableGPUServiceTracing);
+  gpu_preferences.enable_unsafe_es3_apis =
+      command_line->HasSwitch(switches::kEnableUnsafeES3APIs);
+  return gpu_preferences;
+}
+
+}  // namespace content
diff --git a/content/public/browser/gpu_utils.h b/content/public/browser/gpu_utils.h
new file mode 100644
index 0000000..84e7808
--- /dev/null
+++ b/content/public/browser/gpu_utils.h
@@ -0,0 +1,17 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_GPU_UTILS_H_
+#define CONTENT_PUBLIC_BROWSER_GPU_UTILS_H_
+
+#include "content/common/content_export.h"
+#include "gpu/command_buffer/service/gpu_preferences.h"
+
+namespace content {
+
+CONTENT_EXPORT const gpu::GpuPreferences GetGpuPreferencesFromCommandLine();
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_BROWSER_GPU_UTILS_H_
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestBase.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestBase.java
index b4528ed..7a5d4bba1 100644
--- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestBase.java
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestBase.java
@@ -6,6 +6,7 @@
 
 import android.test.InstrumentationTestCase;
 
+import org.chromium.base.PathUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.library_loader.LibraryProcessType;
@@ -17,6 +18,8 @@
  * Test extension that adds support for loading and dealing with native libraries.
  */
 public class NativeLibraryTestBase extends InstrumentationTestCase {
+    private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "content";
+
     /**
      * Loads the native library on the activity UI thread (must not be called from the UI thread).
      */
@@ -35,6 +38,9 @@
     private void handleNativeInitialization(final boolean initBrowserProcess) {
         assertFalse(ThreadUtils.runningOnUiThread());
 
+        PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX,
+                getInstrumentation().getTargetContext());
+
         try {
             ApplicationUtils.waitForLibraryDependencies(getInstrumentation());
         } catch (InterruptedException e) {
diff --git a/content/public/test/content_browser_test.cc b/content/public/test/content_browser_test.cc
index 64208f7..ad300e2 100644
--- a/content/public/test/content_browser_test.cc
+++ b/content/public/test/content_browser_test.cc
@@ -66,7 +66,7 @@
     // setting a global that may be used after ContentBrowserTest is
     // destroyed.
     ContentRendererClient* old_client =
-        command_line->HasSwitch(switches::kRunLayoutTest)
+        switches::IsRunLayoutTestSwitchPresent()
             ? SetRendererClientForTesting(new LayoutTestContentRendererClient)
             : SetRendererClientForTesting(new ShellContentRendererClient);
     // No-one should have set this value before we did.
@@ -106,8 +106,7 @@
 }
 
 void ContentBrowserTest::RunTestOnMainThreadLoop() {
-  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kRunLayoutTest)) {
+  if (!switches::IsRunLayoutTestSwitchPresent()) {
     CHECK_EQ(Shell::windows().size(), 1u);
     shell_ = Shell::windows()[0];
   }
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc
index 1936535..b4094e0 100644
--- a/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -162,19 +162,22 @@
     tree_data.sel_focus_offset = focus_offset;
   }
 
-  // Get the tree ID for this frame and possibly the parent frame.
+  // Get the tree ID for this frame and the parent frame.
   WebLocalFrame* web_frame = document.frame();
   if (web_frame) {
     RenderFrame* render_frame = RenderFrame::FromWebFrame(web_frame);
     tree_data.routing_id = render_frame->GetRoutingID();
 
-    // Get the tree ID for the parent frame, if it's remote.
-    // (If it's local, it's already part of this same tree.)
+    // Get the tree ID for the parent frame.
     blink::WebFrame* parent_web_frame = web_frame->parent();
     if (parent_web_frame && parent_web_frame->isWebRemoteFrame()) {
       RenderFrameProxy* parent_render_frame_proxy =
           RenderFrameProxy::FromWebFrame(parent_web_frame);
       tree_data.parent_routing_id = parent_render_frame_proxy->routing_id();
+    } else if (parent_web_frame && parent_web_frame->isWebLocalFrame()) {
+      RenderFrame* parent_render_frame = RenderFrame::FromWebFrame(
+          parent_web_frame);
+      tree_data.parent_routing_id = parent_render_frame->GetRoutingID();
     }
   }
 
@@ -465,10 +468,9 @@
           browser_plugin->browser_plugin_instance_id());
     }
 
-    // Out-of-process iframe.
+    // Iframe.
     if (is_iframe) {
       WebFrame* frame = WebFrame::fromFrameOwnerElement(element);
-
       if (frame && frame->isWebRemoteFrame()) {
         RenderFrameProxy* render_frame_proxy =
             RenderFrameProxy::FromWebFrame(frame);
@@ -476,6 +478,12 @@
         dst->AddContentIntAttribute(
             AX_CONTENT_ATTR_CHILD_ROUTING_ID,
             render_frame_proxy->routing_id());
+      } else if (frame && frame->isWebLocalFrame()) {
+        RenderFrame* render_frame = RenderFrame::FromWebFrame(frame);
+        DCHECK(render_frame);
+        dst->AddContentIntAttribute(
+            AX_CONTENT_ATTR_CHILD_ROUTING_ID,
+            render_frame->GetRoutingID());
       }
     }
   }
diff --git a/content/renderer/accessibility/renderer_accessibility_browsertest.cc b/content/renderer/accessibility/renderer_accessibility_browsertest.cc
index ec6ac0a5..f085593 100644
--- a/content/renderer/accessibility/renderer_accessibility_browsertest.cc
+++ b/content/renderer/accessibility/renderer_accessibility_browsertest.cc
@@ -403,59 +403,4 @@
   // so we don't have a test expectation for it.
 }
 
-TEST_F(RendererAccessibilityTest, EventOnDetachedNodeTriggersMainFrameLayout) {
-  std::string html =
-      "<body>"
-      "  <iframe srcdoc='<input>'></iframe>"
-      "  <button>Button</button>"
-      "</body>";
-  LoadHTML(html.c_str());
-
-  scoped_ptr<TestRendererAccessibility> accessibility(
-      new TestRendererAccessibility(frame()));
-  accessibility->SendPendingAccessibilityEvents();
-
-  WebDocument document = view()->GetWebView()->mainFrame()->document();
-  WebAXObject root_obj = document.accessibilityObject();
-  ASSERT_EQ(blink::WebAXRoleWebArea, root_obj.role());
-  WebAXObject group = root_obj.childAt(0);
-  ASSERT_EQ(blink::WebAXRoleGroup, group.role());
-  WebAXObject iframe = group.childAt(0);
-  ASSERT_EQ(blink::WebAXRoleIframe, iframe.role());
-  WebAXObject child_doc = iframe.childAt(0);
-  ASSERT_EQ(blink::WebAXRoleWebArea, child_doc.role());
-  WebAXObject child_group = child_doc.childAt(0);
-  ASSERT_EQ(blink::WebAXRoleGroup, child_group.role());
-  WebAXObject child_textfield = child_group.childAt(0);
-  ASSERT_EQ(blink::WebAXRoleTextField, child_textfield.role());
-
-  // Hide the input element inside the iframe.
-  ExecuteJavaScriptForTests(
-      "document.querySelector('iframe').contentDocument"
-      ".querySelector('input').style.display = 'none';");
-  accessibility->HandleAXEvent(
-      child_textfield,
-      ui::AX_EVENT_LAYOUT_COMPLETE);
-  accessibility->SendPendingAccessibilityEvents();
-
-  // Make sure |child_textfield| is invalid now.
-  ASSERT_TRUE(child_textfield.isDetached());
-
-  // Now do a random style change in the iframe to make its layout not clean.
-  ExecuteJavaScriptForTests(
-      "var doc = document.querySelector('iframe').contentDocument; "
-      "doc.body.style.backgroundColor = '#f00';");
-
-  // Now try to handle a "layout complete" event on the detached textfield
-  // object. The event handling will be a no-op, but the layout complete
-  // will trigger calling SendLocationChanges. Make sure that
-  // SendLocationChanges doesn't depend on layout in the main frame being
-  // clean.
-  //
-  // If this doesn't crash, the test passes.
-  accessibility->HandleAXEvent(child_textfield,
-                               ui::AX_EVENT_LAYOUT_COMPLETE);
-  accessibility->SendPendingAccessibilityEvents();
-}
-
 }  // namespace content
diff --git a/content/renderer/dom_serializer_browsertest.cc b/content/renderer/dom_serializer_browsertest.cc
index a16ee720..3c3e549 100644
--- a/content/renderer/dom_serializer_browsertest.cc
+++ b/content/renderer/dom_serializer_browsertest.cc
@@ -640,15 +640,11 @@
 
 // If original contents have document type, the serialized contents also have
 // document type.
-// Disabled by ellyjones@ on 2015-05-18, see https://crbug.com/488495.
-#if defined(OS_MACOSX)
-#define MAYBE_SerializeHTMLDOMWithDocType DISABLED_SerializeHTMLDOMWithDocType
-#else
-#define MAYBE_SerializeHTMLDOMWithDocType SerializeHTMLDOMWithDocType
-#endif
+// Disabled on OSX by ellyjones@ on 2015-05-18, see https://crbug.com/488495,
+// on all platforms by tsergeant@ on 2016-03-10, see https://crbug.com/593575
 
 IN_PROC_BROWSER_TEST_F(DomSerializerTests,
-                       MAYBE_SerializeHTMLDOMWithDocType) {
+                       DISABLED_SerializeHTMLDOMWithDocType) {
   base::FilePath page_file_path =
       GetTestFilePath("dom_serializer", "youtube_1.htm");
   GURL file_url = net::FilePathToFileURL(page_file_path);
@@ -725,16 +721,11 @@
 // declaration as first child of HEAD element for resolving WebKit bug:
 // http://bugs.webkit.org/show_bug.cgi?id=16621 even the original document
 // does not have META charset declaration.
-// Disabled by battre@ on 2015-05-21, see https://crbug.com/488495.
-#if defined(OS_MACOSX)
-#define MAYBE_SerializeHTMLDOMWithNoMetaCharsetInOriginalDoc \
-  DISABLED_SerializeHTMLDOMWithNoMetaCharsetInOriginalDoc
-#else
-#define MAYBE_SerializeHTMLDOMWithNoMetaCharsetInOriginalDoc \
-  SerializeHTMLDOMWithNoMetaCharsetInOriginalDoc
-#endif
-IN_PROC_BROWSER_TEST_F(DomSerializerTests,
-                       MAYBE_SerializeHTMLDOMWithNoMetaCharsetInOriginalDoc) {
+// Disabled on OSX by battre@ on 2015-05-21, see https://crbug.com/488495,
+// on all platforms by tsergeant@ on 2016-03-10, see https://crbug.com/593575
+IN_PROC_BROWSER_TEST_F(
+    DomSerializerTests,
+    DISABLED_SerializeHTMLDOMWithNoMetaCharsetInOriginalDoc) {
   base::FilePath page_file_path =
       GetTestFilePath("dom_serializer", "youtube_1.htm");
   // Get file URL.
diff --git a/content/renderer/java/gin_java_bridge_value_converter_unittest.cc b/content/renderer/java/gin_java_bridge_value_converter_unittest.cc
index 2178fca..2de3e12 100644
--- a/content/renderer/java/gin_java_bridge_value_converter_unittest.cc
+++ b/content/renderer/java/gin_java_bridge_value_converter_unittest.cc
@@ -12,7 +12,6 @@
 #include "content/common/android/gin_java_bridge_value.h"
 #include "content/renderer/java/gin_java_bridge_value_converter.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 namespace content {
@@ -100,7 +99,6 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   scoped_ptr<GinJavaBridgeValueConverter> converter(
       new GinJavaBridgeValueConverter());
diff --git a/content/renderer/media/canvas_capture_handler.cc b/content/renderer/media/canvas_capture_handler.cc
index 4a44740..15ebf05 100644
--- a/content/renderer/media/canvas_capture_handler.cc
+++ b/content/renderer/media/canvas_capture_handler.cc
@@ -38,6 +38,7 @@
       int max_requested_height,
       double max_requested_frame_rate,
       const VideoCaptureDeviceFormatsCB& callback) override {
+    DCHECK(main_render_thread_checker_.CalledOnValidThread());
     const blink::WebSize& size = canvas_handler_->GetSourceSize();
     media::VideoCaptureFormats formats;
     formats.push_back(
@@ -51,15 +52,19 @@
   void StartCapture(const media::VideoCaptureParams& params,
                     const VideoCaptureDeliverFrameCB& frame_callback,
                     const RunningCallback& running_callback) override {
+    DCHECK(main_render_thread_checker_.CalledOnValidThread());
     canvas_handler_->StartVideoCapture(params, frame_callback,
                                        running_callback);
   }
   void StopCapture() override {
+    DCHECK(main_render_thread_checker_.CalledOnValidThread());
     canvas_handler_->StopVideoCapture();
   }
 
  private:
   double frame_rate_;
+  // Bound to Main Render thread.
+  base::ThreadChecker main_render_thread_checker_;
   // CanvasCaptureHandler is owned by CanvasDrawListener in blink and
   // guaranteed to be alive during the lifetime of this class.
   base::WeakPtr<CanvasCaptureHandler> canvas_handler_;
@@ -71,16 +76,16 @@
       media::VideoCapturerSource::VideoCaptureDeliverFrameCB new_frame_callback)
       : new_frame_callback_(new_frame_callback),
         weak_ptr_factory_(this) {
-    thread_checker_.DetachFromThread();
+    io_thread_checker_.DetachFromThread();
   }
   ~CanvasCaptureHandlerDelegate() {
-    DCHECK(thread_checker_.CalledOnValidThread());
+    DCHECK(io_thread_checker_.CalledOnValidThread());
   }
 
   void SendNewFrameOnIOThread(
       const scoped_refptr<media::VideoFrame>& video_frame,
       const base::TimeTicks& current_time) {
-    DCHECK(thread_checker_.CalledOnValidThread());
+    DCHECK(io_thread_checker_.CalledOnValidThread());
     new_frame_callback_.Run(video_frame, current_time);
   }
 
@@ -91,7 +96,8 @@
  private:
   const media::VideoCapturerSource::VideoCaptureDeliverFrameCB
       new_frame_callback_;
-  base::ThreadChecker thread_checker_;
+  // Bound to IO thread.
+  base::ThreadChecker io_thread_checker_;
   base::WeakPtrFactory<CanvasCaptureHandlerDelegate> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(CanvasCaptureHandlerDelegate);
@@ -114,7 +120,7 @@
 
 CanvasCaptureHandler::~CanvasCaptureHandler() {
   DVLOG(3) << __FUNCTION__;
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(main_render_thread_checker_.CalledOnValidThread());
   io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release());
 }
 
@@ -132,12 +138,12 @@
 }
 
 void CanvasCaptureHandler::sendNewFrame(const SkImage* image) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(main_render_thread_checker_.CalledOnValidThread());
   CreateNewFrame(image);
 }
 
 bool CanvasCaptureHandler::needsNewFrame() const {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(main_render_thread_checker_.CalledOnValidThread());
   return ask_for_new_frame_;
 }
 
@@ -148,8 +154,8 @@
     const media::VideoCapturerSource::RunningCallback& running_callback) {
   DVLOG(3) << __FUNCTION__ << " requested "
            << media::VideoCaptureFormat::ToString(params.requested_format);
+  DCHECK(main_render_thread_checker_.CalledOnValidThread());
   DCHECK(params.requested_format.IsValid());
-  DCHECK(thread_checker_.CalledOnValidThread());
 
   // TODO(emircan): Accomodate to the given frame rate constraints here.
   capture_format_ = params.requested_format;
@@ -161,13 +167,13 @@
 
 void CanvasCaptureHandler::StopVideoCapture() {
   DVLOG(3) << __FUNCTION__;
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(main_render_thread_checker_.CalledOnValidThread());
   ask_for_new_frame_ = false;
   io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release());
 }
 
 void CanvasCaptureHandler::CreateNewFrame(const SkImage* image) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(main_render_thread_checker_.CalledOnValidThread());
   DCHECK(image);
 
   const gfx::Size size(image->width(), image->height());
@@ -213,7 +219,7 @@
       base::Bind(&CanvasCaptureHandler::CanvasCaptureHandlerDelegate::
                      SendNewFrameOnIOThread,
                  delegate_->GetWeakPtrForIOThread(), video_frame,
-                 base::TimeTicks()));
+                 base::TimeTicks::Now()));
 }
 
 void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack(
diff --git a/content/renderer/media/canvas_capture_handler.h b/content/renderer/media/canvas_capture_handler.h
index c9aa313..a4bbec4b 100644
--- a/content/renderer/media/canvas_capture_handler.h
+++ b/content/renderer/media/canvas_capture_handler.h
@@ -92,8 +92,9 @@
 
   const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
   scoped_ptr<CanvasCaptureHandlerDelegate> delegate_;
-  // Bound to the main render thread.
-  base::ThreadChecker thread_checker_;
+
+  // Bound to Main Render thread.
+  base::ThreadChecker main_render_thread_checker_;
   base::WeakPtrFactory<CanvasCaptureHandler> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(CanvasCaptureHandler);
diff --git a/content/renderer/media/canvas_capture_handler_unittest.cc b/content/renderer/media/canvas_capture_handler_unittest.cc
index 8c449a3c..e17ffc6 100644
--- a/content/renderer/media/canvas_capture_handler_unittest.cc
+++ b/content/renderer/media/canvas_capture_handler_unittest.cc
@@ -100,6 +100,8 @@
     else
       EXPECT_EQ(media::PIXEL_FORMAT_YV12A, video_frame->format());
 
+    EXPECT_EQ(video_frame->timestamp().InMilliseconds(),
+              (estimated_capture_time - base::TimeTicks()).InMilliseconds());
     const gfx::Size& size = video_frame->coded_size();
     EXPECT_EQ(kTestCanvasCaptureFrameWidth, size.width());
     EXPECT_EQ(kTestCanvasCaptureFrameHeight, size.height());
diff --git a/content/renderer/media/media_stream_audio_level_calculator.h b/content/renderer/media/media_stream_audio_level_calculator.h
index f093ab4..792e65c3 100644
--- a/content/renderer/media/media_stream_audio_level_calculator.h
+++ b/content/renderer/media/media_stream_audio_level_calculator.h
@@ -26,7 +26,7 @@
   // Provides thread-safe access to the current signal level.  This object is
   // intended to be passed to modules running on other threads that poll for the
   // current signal level.
-  class Level : public base::RefCountedThreadSafe<Level> {
+  class CONTENT_EXPORT Level : public base::RefCountedThreadSafe<Level> {
    public:
     float GetCurrent() const;
 
diff --git a/content/renderer/pepper/v8_var_converter_unittest.cc b/content/renderer/pepper/v8_var_converter_unittest.cc
index e030ffdb..cd07abb 100644
--- a/content/renderer/pepper/v8_var_converter_unittest.cc
+++ b/content/renderer/pepper/v8_var_converter_unittest.cc
@@ -29,7 +29,6 @@
 #include "ppapi/shared_impl/var.h"
 #include "ppapi/shared_impl/var_tracker.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 using ppapi::ArrayBufferVar;
@@ -404,7 +403,6 @@
     v8::Local<v8::Context> context =
         v8::Local<v8::Context>::New(isolate_, context_);
     v8::Context::Scope context_scope(context);
-    blink::WebScopedMicrotaskSuppression microtasks_scope;
 
     const char* source =
         "(function() {"
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 3606271d..2dbf048 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -145,6 +145,8 @@
     "browser/shell_web_contents_view_delegate_win.cc",
     "common/layout_test/layout_test_messages.cc",
     "common/layout_test/layout_test_messages.h",
+    "common/layout_test/layout_test_switches.cc",
+    "common/layout_test/layout_test_switches.h",
     "common/leak_detection_result.h",
     "common/shell_content_client.cc",
     "common/shell_content_client.h",
diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc
index 298f6736..5a4c73f 100644
--- a/content/shell/app/shell_main_delegate.cc
+++ b/content/shell/app/shell_main_delegate.cc
@@ -26,6 +26,7 @@
 #include "content/shell/browser/layout_test/layout_test_content_browser_client.h"
 #include "content/shell/browser/shell_browser_main.h"
 #include "content/shell/browser/shell_content_browser_client.h"
+#include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/shell_switches.h"
 #include "content/shell/renderer/layout_test/layout_test_content_renderer_client.h"
 #include "content/shell/renderer/shell_content_renderer_client.h"
diff --git a/content/shell/app/shell_main_delegate_mac.mm b/content/shell/app/shell_main_delegate_mac.mm
index bba20a1..298475c 100644
--- a/content/shell/app/shell_main_delegate_mac.mm
+++ b/content/shell/app/shell_main_delegate_mac.mm
@@ -28,8 +28,7 @@
       [[NSMutableDictionary alloc]
           initWithContentsOfFile:base::mac::FilePathToNSString(info_plist)]);
 
-  bool running_layout_tests = base::CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kRunLayoutTest);
+  bool running_layout_tests = switches::IsRunLayoutTestSwitchPresent();
   bool not_high_resolution_capable =
       [info_dict objectForKey:kHighResolutionCapable] &&
       [[info_dict objectForKey:kHighResolutionCapable] isEqualToNumber:@(NO)];
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc
index 3ad8040c2..15d0f39 100644
--- a/content/shell/browser/layout_test/blink_test_controller.cc
+++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -44,8 +44,8 @@
 #include "content/shell/browser/shell_browser_context.h"
 #include "content/shell/browser/shell_content_browser_client.h"
 #include "content/shell/browser/shell_devtools_frontend.h"
+#include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/shell_messages.h"
-#include "content/shell/common/shell_switches.h"
 #include "content/shell/renderer/layout_test/blink_test_helpers.h"
 #include "ui/gfx/codec/png_codec.h"
 
diff --git a/content/shell/browser/layout_test/layout_test_browser_main.cc b/content/shell/browser/layout_test/layout_test_browser_main.cc
index 2984a09..e5b191e 100644
--- a/content/shell/browser/layout_test/layout_test_browser_main.cc
+++ b/content/shell/browser/layout_test/layout_test_browser_main.cc
@@ -24,6 +24,7 @@
 #include "content/shell/browser/layout_test/blink_test_controller.h"
 #include "content/shell/browser/layout_test/test_info_extractor.h"
 #include "content/shell/browser/shell.h"
+#include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/shell_switches.h"
 #include "content/shell/renderer/layout_test/blink_test_helpers.h"
 #include "net/base/filename_util.h"
diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.cc b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
index 227478d..8626064ea 100644
--- a/content/shell/browser/layout_test/layout_test_content_browser_client.cc
+++ b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
@@ -18,8 +18,8 @@
 #include "content/shell/browser/layout_test/layout_test_notification_manager.h"
 #include "content/shell/browser/layout_test/layout_test_resource_dispatcher_host_delegate.h"
 #include "content/shell/browser/shell_browser_context.h"
+#include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/shell_messages.h"
-#include "content/shell/common/shell_switches.h"
 #include "content/shell/renderer/layout_test/blink_test_helpers.h"
 
 namespace content {
@@ -89,6 +89,29 @@
   command_line->AppendSwitch(switches::kRunLayoutTest);
   ShellContentBrowserClient::AppendExtraCommandLineSwitches(command_line,
                                                             child_process_id);
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kAlwaysUseComplexText)) {
+    command_line->AppendSwitch(switches::kAlwaysUseComplexText);
+  }
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableFontAntialiasing)) {
+    command_line->AppendSwitch(switches::kEnableFontAntialiasing);
+  }
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kExposeInternalsForTesting)) {
+    command_line->AppendSwitch(switches::kExposeInternalsForTesting);
+  }
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kStableReleaseMode)) {
+    command_line->AppendSwitch(switches::kStableReleaseMode);
+  }
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableLeakDetection)) {
+    command_line->AppendSwitchASCII(
+        switches::kEnableLeakDetection,
+        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+            switches::kEnableLeakDetection));
+  }
 }
 
 BrowserMainParts* LayoutTestContentBrowserClient::CreateBrowserMainParts(
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc
index 67921503..ed655f35 100644
--- a/content/shell/browser/shell.cc
+++ b/content/shell/browser/shell.cc
@@ -77,9 +77,7 @@
       url_edit_view_(NULL),
 #endif
       headless_(false) {
-  const base::CommandLine& command_line =
-      *base::CommandLine::ForCurrentProcess();
-  if (command_line.HasSwitch(switches::kRunLayoutTest))
+  if (switches::IsRunLayoutTestSwitchPresent())
     headless_ = true;
   windows_.push_back(this);
 
@@ -122,13 +120,13 @@
   // Note: Do not make RenderFrameHost or RenderViewHost specific state changes
   // here, because they will be forgotten after a cross-process navigation. Use
   // RenderFrameCreated or RenderViewCreated instead.
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kRunLayoutTest)) {
+  if (switches::IsRunLayoutTestSwitchPresent()) {
     web_contents->GetMutableRendererPrefs()->use_custom_colors = false;
     web_contents->GetRenderViewHost()->SyncRendererPrefs();
   }
 
 #if defined(ENABLE_WEBRTC)
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kForceWebRtcIPHandlingPolicy)) {
     web_contents->GetMutableRendererPrefs()->webrtc_ip_handling_policy =
         command_line->GetSwitchValueASCII(
@@ -253,8 +251,7 @@
                            bool user_gesture,
                            bool* was_blocked) {
   CreateShell(new_contents, AdjustWindowSize(initial_rect.size()));
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kRunLayoutTest))
+  if (switches::IsRunLayoutTestSwitchPresent())
     NotifyDoneForwarder::CreateForWebContents(new_contents);
 }
 
@@ -355,8 +352,7 @@
 #if defined(OS_ANDROID)
   PlatformToggleFullscreenModeForTab(web_contents, enter_fullscreen);
 #endif
-  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kRunLayoutTest))
+  if (!switches::IsRunLayoutTestSwitchPresent())
     return;
   if (is_fullscreen_ != enter_fullscreen) {
     is_fullscreen_ = enter_fullscreen;
@@ -406,11 +402,9 @@
 JavaScriptDialogManager* Shell::GetJavaScriptDialogManager(
     WebContents* source) {
   if (!dialog_manager_) {
-    const base::CommandLine& command_line =
-        *base::CommandLine::ForCurrentProcess();
-    dialog_manager_.reset(command_line.HasSwitch(switches::kRunLayoutTest)
-        ? new LayoutTestJavaScriptDialogManager
-        : new ShellJavaScriptDialogManager);
+    dialog_manager_.reset(switches::IsRunLayoutTestSwitchPresent()
+                              ? new LayoutTestJavaScriptDialogManager
+                              : new ShellJavaScriptDialogManager);
   }
   return dialog_manager_.get();
 }
@@ -418,9 +412,7 @@
 scoped_ptr<BluetoothChooser> Shell::RunBluetoothChooser(
     RenderFrameHost* frame,
     const BluetoothChooser::EventHandler& event_handler) {
-  const base::CommandLine& command_line =
-      *base::CommandLine::ForCurrentProcess();
-  if (command_line.HasSwitch(switches::kRunLayoutTest)) {
+  if (switches::IsRunLayoutTestSwitchPresent()) {
     return BlinkTestController::Get()->RunBluetoothChooser(frame,
                                                            event_handler);
   }
@@ -432,15 +424,12 @@
                                 const base::string16& message,
                                 int32_t line_no,
                                 const base::string16& source_id) {
-  return base::CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kRunLayoutTest);
+  return switches::IsRunLayoutTestSwitchPresent();
 }
 
 void Shell::RendererUnresponsive(WebContents* source) {
-  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kRunLayoutTest))
-    return;
-  BlinkTestController::Get()->RendererUnresponsive();
+  if (switches::IsRunLayoutTestSwitchPresent())
+    BlinkTestController::Get()->RendererUnresponsive();
 }
 
 void Shell::ActivateContents(WebContents* contents) {
@@ -471,8 +460,7 @@
 
 void Shell::RenderViewCreated(RenderViewHost* render_view_host) {
   // All RenderViewHosts in layout tests should get Mojo bindings.
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kRunLayoutTest))
+  if (switches::IsRunLayoutTestSwitchPresent())
     render_view_host->AllowBindings(BINDINGS_POLICY_MOJO);
 }
 
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 39eb87e..4fe9084 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -234,22 +234,6 @@
     base::CommandLine* command_line,
     int child_process_id) {
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableFontAntialiasing)) {
-    command_line->AppendSwitch(switches::kEnableFontAntialiasing);
-  }
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kAlwaysUseComplexText)) {
-    command_line->AppendSwitch(switches::kAlwaysUseComplexText);
-  }
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kExposeInternalsForTesting)) {
-    command_line->AppendSwitch(switches::kExposeInternalsForTesting);
-  }
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kStableReleaseMode)) {
-    command_line->AppendSwitch(switches::kStableReleaseMode);
-  }
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableCrashReporter)) {
     command_line->AppendSwitch(switches::kEnableCrashReporter);
   }
@@ -261,13 +245,6 @@
             switches::kCrashDumpsDir));
   }
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableLeakDetection)) {
-    command_line->AppendSwitchASCII(
-        switches::kEnableLeakDetection,
-        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-            switches::kEnableLeakDetection));
-  }
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kIsolateSitesForTesting)) {
     command_line->AppendSwitchASCII(
         switches::kIsolateSitesForTesting,
diff --git a/content/shell/browser/shell_web_contents_view_delegate_mac.mm b/content/shell/browser/shell_web_contents_view_delegate_mac.mm
index 5d8ecdd..8cfc1d7b2 100644
--- a/content/shell/browser/shell_web_contents_view_delegate_mac.mm
+++ b/content/shell/browser/shell_web_contents_view_delegate_mac.mm
@@ -95,8 +95,7 @@
 void ShellWebContentsViewDelegate::ShowContextMenu(
     RenderFrameHost* render_frame_host,
     const ContextMenuParams& params) {
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kRunLayoutTest))
+  if (switches::IsRunLayoutTestSwitchPresent())
     return;
 
   params_ = params;
diff --git a/content/shell/browser/shell_web_contents_view_delegate_win.cc b/content/shell/browser/shell_web_contents_view_delegate_win.cc
index d71bf0d..3ae4d2a8 100644
--- a/content/shell/browser/shell_web_contents_view_delegate_win.cc
+++ b/content/shell/browser/shell_web_contents_view_delegate_win.cc
@@ -72,8 +72,7 @@
 void ShellWebContentsViewDelegate::ShowContextMenu(
     RenderFrameHost* render_frame_host,
     const ContextMenuParams& params) {
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kRunLayoutTest))
+  if (switches::IsRunLayoutTestSwitchPresent())
     return;
 
   params_ = params;
diff --git a/content/shell/common/layout_test/layout_test_switches.cc b/content/shell/common/layout_test/layout_test_switches.cc
new file mode 100644
index 0000000..46cf86470
--- /dev/null
+++ b/content/shell/common/layout_test/layout_test_switches.cc
@@ -0,0 +1,52 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/shell/common/layout_test/layout_test_switches.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_split.h"
+
+namespace switches {
+
+// Allow access to external pages during layout tests.
+const char kAllowExternalPages[] = "allow-external-pages";
+
+// Check whether all system dependencies for running layout tests are met.
+const char kCheckLayoutTestSysDeps[] = "check-layout-test-sys-deps";
+
+// When specified to "enable-leak-detection" command-line option,
+// causes the leak detector to cause immediate crash when found leak.
+const char kCrashOnFailure[] = "crash-on-failure";
+
+// Enable accelerated 2D canvas.
+const char kEnableAccelerated2DCanvas[] = "enable-accelerated-2d-canvas";
+
+// Enable font antialiasing for pixel tests.
+const char kEnableFontAntialiasing[] = "enable-font-antialiasing";
+
+// Always use the complex text path for layout tests.
+const char kAlwaysUseComplexText[] = "always-use-complex-text";
+
+// Enables the leak detection of loading webpages. This allows us to check
+// whether or not reloading a webpage releases web-related objects correctly.
+const char kEnableLeakDetection[] = "enable-leak-detection";
+
+// Encode binary layout test results (images, audio) using base64.
+const char kEncodeBinary[] = "encode-binary";
+
+// Exposes the window.internals object to JavaScript for interactive development
+// and debugging of layout tests that rely on it.
+const char kExposeInternalsForTesting[] = "expose-internals-for-testing";
+
+// Request the render trees of pages to be dumped as text once they have
+// finished loading.
+const char kRunLayoutTest[] = "run-layout-test";
+
+// This makes us disable some web-platform runtime features so that we test
+// content_shell as if it was a stable release. It is only followed when
+// kRunLayoutTest is set. For the features' level, see
+// http://dev.chromium.org/blink/runtime-enabled-features.
+const char kStableReleaseMode[] = "stable-release-mode";
+
+}  // namespace switches
diff --git a/content/shell/common/layout_test/layout_test_switches.h b/content/shell/common/layout_test/layout_test_switches.h
new file mode 100644
index 0000000..fbcef12
--- /dev/null
+++ b/content/shell/common/layout_test/layout_test_switches.h
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Defines all the "layout_test" command-line switches.
+
+#ifndef CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_SWITCHES_H_
+#define CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_SWITCHES_H_
+
+#include <string>
+#include <vector>
+
+namespace switches {
+
+extern const char kAllowExternalPages[];
+extern const char kCheckLayoutTestSysDeps[];
+extern const char kCrashOnFailure[];
+extern const char kEnableAccelerated2DCanvas[];
+extern const char kEnableFontAntialiasing[];
+extern const char kAlwaysUseComplexText[];
+extern const char kEnableLeakDetection[];
+extern const char kEncodeBinary[];
+extern const char kExposeInternalsForTesting[];
+extern const char kRunLayoutTest[];
+extern const char kStableReleaseMode[];
+
+}  // namespace switches
+
+#endif  // CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_SWITCHES_H_
diff --git a/content/shell/common/shell_content_client.cc b/content/shell/common/shell_content_client.cc
index d0940b8..842e0c1 100644
--- a/content/shell/common/shell_content_client.cc
+++ b/content/shell/common/shell_content_client.cc
@@ -36,8 +36,7 @@
 }
 
 base::string16 ShellContentClient::GetLocalizedString(int message_id) const {
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kRunLayoutTest)) {
+  if (switches::IsRunLayoutTestSwitchPresent()) {
     switch (message_id) {
       case IDS_FORM_OTHER_DATE_LABEL:
         return base::ASCIIToUTF16("<<OtherDateLabel>>");
@@ -63,8 +62,7 @@
 base::StringPiece ShellContentClient::GetDataResource(
     int resource_id,
     ui::ScaleFactor scale_factor) const {
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kRunLayoutTest)) {
+  if (switches::IsRunLayoutTestSwitchPresent()) {
     switch (resource_id) {
       case IDR_BROKENIMAGE:
 #if defined(OS_MACOSX)
diff --git a/content/shell/common/shell_switches.cc b/content/shell/common/shell_switches.cc
index a125244..09a3817 100644
--- a/content/shell/common/shell_switches.cc
+++ b/content/shell/common/shell_switches.cc
@@ -6,15 +6,10 @@
 
 #include "base/command_line.h"
 #include "base/strings/string_split.h"
+#include "content/shell/common/layout_test/layout_test_switches.h"
 
 namespace switches {
 
-// Allow access to external pages during layout tests.
-const char kAllowExternalPages[] = "allow-external-pages";
-
-// Check whether all system dependencies for running layout tests are met.
-const char kCheckLayoutTestSysDeps[] = "check-layout-test-sys-deps";
-
 // Tells Content Shell that it's running as a content_browsertest.
 const char kContentBrowserTest[] = "browser-test";
 
@@ -24,30 +19,6 @@
 // The directory breakpad should store minidumps in.
 const char kCrashDumpsDir[] = "crash-dumps-dir";
 
-// When specified to "enable-leak-detection" command-line option,
-// causes the leak detector to cause immediate crash when found leak.
-const char kCrashOnFailure[] = "crash-on-failure";
-
-// Enable accelerated 2D canvas.
-const char kEnableAccelerated2DCanvas[] = "enable-accelerated-2d-canvas";
-
-// Enable font antialiasing for pixel tests.
-const char kEnableFontAntialiasing[] = "enable-font-antialiasing";
-
-// Always use the complex text path for layout tests.
-const char kAlwaysUseComplexText[] = "always-use-complex-text";
-
-// Enables the leak detection of loading webpages. This allows us to check
-// whether or not reloading a webpage releases web-related objects correctly.
-const char kEnableLeakDetection[] = "enable-leak-detection";
-
-// Encode binary layout test results (images, audio) using base64.
-const char kEncodeBinary[] = "encode-binary";
-
-// Exposes the window.internals object to JavaScript for interactive development
-// and debugging of layout tests that rely on it.
-const char kExposeInternalsForTesting[] = "expose-internals-for-testing";
-
 // Enable site isolation (--site-per-process style isolation) for a subset of
 // sites. The argument is a wildcard pattern which will be matched against the
 // site URL to determine which sites to isolate. This can be used to isolate
@@ -61,16 +32,6 @@
 // with a semicolon (;).
 const char kRegisterFontFiles[] = "register-font-files";
 
-// Request the render trees of pages to be dumped as text once they have
-// finished loading.
-const char kRunLayoutTest[] = "run-layout-test";
-
-// This makes us disable some web-platform runtime features so that we test
-// content_shell as if it was a stable release. It is only followed when
-// kRunLayoutTest is set. For the features' level, see
-// http://dev.chromium.org/blink/runtime-enabled-features.
-const char kStableReleaseMode[] = "stable-release-mode";
-
 // Size for the content_shell's host window (i.e. "800x600").
 const char kContentShellHostWindowSize[] = "content-shell-host-window-size";
 
@@ -86,4 +47,9 @@
   return files;
 }
 
+bool IsRunLayoutTestSwitchPresent() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kRunLayoutTest);
+}
+
 }  // namespace switches
diff --git a/content/shell/common/shell_switches.h b/content/shell/common/shell_switches.h
index 4c61a11..5ee6fde 100644
--- a/content/shell/common/shell_switches.h
+++ b/content/shell/common/shell_switches.h
@@ -12,27 +12,22 @@
 
 namespace switches {
 
-extern const char kAllowExternalPages[];
-extern const char kCheckLayoutTestSysDeps[];
 extern const char kContentBrowserTest[];
 extern const char kContentShellDataPath[];
 extern const char kCrashDumpsDir[];
-extern const char kCrashOnFailure[];
-extern const char kEnableAccelerated2DCanvas[];
-extern const char kEnableFontAntialiasing[];
-extern const char kAlwaysUseComplexText[];
-extern const char kEnableLeakDetection[];
-extern const char kEncodeBinary[];
-extern const char kExposeInternalsForTesting[];
 extern const char kIsolateSitesForTesting[];
 extern const char kRegisterFontFiles[];
-extern const char kRunLayoutTest[];
-extern const char kStableReleaseMode[];
 extern const char kContentShellHostWindowSize[];
 
 // Returns list of extra font files to be made accessible to the renderer.
 std::vector<std::string> GetSideloadFontFiles();
 
+// Tells if content shell is running layout tests.
+// TODO(lukasza): The function below somewhat violates the layering (by
+// enabling shell -> layout_tests dependency) but at least narrows the extent of
+// the dependency to a single switch...
+bool IsRunLayoutTestSwitchPresent();
+
 }  // namespace switches
 
 #endif  // CONTENT_SHELL_COMMON_SHELL_SWITCHES_H_
diff --git a/content/shell/renderer/layout_test/blink_test_helpers.cc b/content/shell/renderer/layout_test/blink_test_helpers.cc
index 029c85b..d686988 100644
--- a/content/shell/renderer/layout_test/blink_test_helpers.cc
+++ b/content/shell/renderer/layout_test/blink_test_helpers.cc
@@ -12,7 +12,7 @@
 #include "components/test_runner/test_preferences.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/web_preferences.h"
-#include "content/shell/common/shell_switches.h"
+#include "content/shell/common/layout_test/layout_test_switches.h"
 
 namespace content {
 
diff --git a/content/shell/renderer/layout_test/layout_test_render_process_observer.cc b/content/shell/renderer/layout_test/layout_test_render_process_observer.cc
index 71d29c4d..02f18151 100644
--- a/content/shell/renderer/layout_test/layout_test_render_process_observer.cc
+++ b/content/shell/renderer/layout_test/layout_test_render_process_observer.cc
@@ -10,8 +10,8 @@
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/test/layouttest_support.h"
+#include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/shell_messages.h"
-#include "content/shell/common/shell_switches.h"
 #include "content/shell/renderer/layout_test/blink_test_runner.h"
 #include "third_party/WebKit/public/web/WebKit.h"
 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
diff --git a/content/shell/renderer/shell_render_view_observer.cc b/content/shell/renderer/shell_render_view_observer.cc
index c24c121..893062c 100644
--- a/content/shell/renderer/shell_render_view_observer.cc
+++ b/content/shell/renderer/shell_render_view_observer.cc
@@ -7,7 +7,7 @@
 #include "base/command_line.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/renderer/render_view_observer.h"
-#include "content/shell/common/shell_switches.h"
+#include "content/shell/common/layout_test/layout_test_switches.h"
 #include "third_party/WebKit/public/web/WebTestingSupport.h"
 #include "third_party/WebKit/public/web/WebView.h"
 
diff --git a/content/test/data/accessibility/event/listbox-focus-expected-mac.txt b/content/test/data/accessibility/event/listbox-focus-expected-mac.txt
index f8b4127b..7843b85 100644
--- a/content/test/data/accessibility/event/listbox-focus-expected-mac.txt
+++ b/content/test/data/accessibility/event/listbox-focus-expected-mac.txt
@@ -1,3 +1 @@
 AXFocusedUIElementChanged on AXList
-AXFocusedUIElementChanged on AXList
-AXFocusedUIElementChanged on AXList
diff --git a/content/test/data/accessibility/html/iframe-coordinates-expected-android.txt b/content/test/data/accessibility/html/iframe-coordinates-expected-android.txt
index a461c7f..a2aa55f 100644
--- a/content/test/data/accessibility/html/iframe-coordinates-expected-android.txt
+++ b/content/test/data/accessibility/html/iframe-coordinates-expected-android.txt
@@ -5,11 +5,11 @@
 ++++android.widget.Button role_description='button' clickable focusable name='Button'
 ++android.view.View
 ++++android.view.View
-++++++android.view.View scrollable
+++++++android.view.View focusable scrollable
 ++++++++android.view.View
 ++++++++++android.widget.Button role_description='button' clickable focusable name='Ordinary Button'
 ++android.view.View
 ++++android.view.View
-++++++android.view.View scrollable
+++++++android.view.View focusable scrollable
 ++++++++android.view.View
-++++++++++android.widget.Button role_description='button' clickable focusable name='Scrolled Button'
\ No newline at end of file
+++++++++++android.widget.Button role_description='button' clickable focusable name='Scrolled Button'
diff --git a/content/test/data/accessibility/html/iframe-coordinates-expected-blink.txt b/content/test/data/accessibility/html/iframe-coordinates-expected-blink.txt
index 4ef1683..7897a6a 100644
--- a/content/test/data/accessibility/html/iframe-coordinates-expected-blink.txt
+++ b/content/test/data/accessibility/html/iframe-coordinates-expected-blink.txt
@@ -5,12 +5,12 @@
 ++++button location=(25, 175) size=(250, 50) name='Button'
 ++div location=(0, 300) size=(300, 150)
 ++++iframe location=(0, 300) size=(300, 100)
-++++++webArea location=(0, 0) size=(300, 100) scrollX=0 scrollXMin=0 scrollXMax=0 scrollY=0 scrollYMin=0 scrollYMax=0
+++++++rootWebArea location=(0, 0) size=(300, 100) scrollX=0 scrollXMin=0 scrollXMax=0 scrollY=0 scrollYMin=0 scrollYMax=0
 ++++++++div location=(0, 0) size=(300, 100)
 ++++++++++button location=(25, 25) size=(250, 50) name='Ordinary Button'
 ++div location=(0, 450) size=(300, 150)
 ++++iframe location=(0, 450) size=(150, 50)
-++++++webArea location=(0, 0) size=(300, 100) scrollX=150 scrollXMin=0 scrollXMax=150 scrollY=50 scrollYMin=0 scrollYMax=50
+++++++rootWebArea location=(0, 0) size=(300, 100) scrollX=150 scrollXMin=0 scrollXMax=150 scrollY=50 scrollYMin=0 scrollYMax=50
 ++++++++div location=(0, 0) size=(300, 100)
 ++++++++++button location=(25, 25) size=(250, 50) name='Scrolled Button'
-<-- End-of-file -->
\ No newline at end of file
+<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/iframe-expected-android.txt b/content/test/data/accessibility/html/iframe-expected-android.txt
index a24ab80..fb37d2b 100644
--- a/content/test/data/accessibility/html/iframe-expected-android.txt
+++ b/content/test/data/accessibility/html/iframe-expected-android.txt
@@ -1,4 +1,4 @@
 android.webkit.WebView focusable focused scrollable
 ++android.view.View
 ++++android.view.View
-++++++android.view.View scrollable
+++++++android.view.View clickable focusable scrollable
diff --git a/content/test/data/accessibility/html/iframe-expected-blink.txt b/content/test/data/accessibility/html/iframe-expected-blink.txt
index 2840d6fbc..0f847ae 100644
--- a/content/test/data/accessibility/html/iframe-expected-blink.txt
+++ b/content/test/data/accessibility/html/iframe-expected-blink.txt
@@ -1,5 +1,5 @@
 rootWebArea
 ++group
 ++++iframe
-++++++webArea
-<-- End-of-file -->
\ No newline at end of file
+++++++rootWebArea
+<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/iframe-presentational-expected-android.txt b/content/test/data/accessibility/html/iframe-presentational-expected-android.txt
index a24ab80..fb37d2b 100644
--- a/content/test/data/accessibility/html/iframe-presentational-expected-android.txt
+++ b/content/test/data/accessibility/html/iframe-presentational-expected-android.txt
@@ -1,4 +1,4 @@
 android.webkit.WebView focusable focused scrollable
 ++android.view.View
 ++++android.view.View
-++++++android.view.View scrollable
+++++++android.view.View clickable focusable scrollable
diff --git a/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-android.txt b/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-android.txt
index a3e75ba..89eeafa 100644
--- a/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-android.txt
+++ b/content/test/data/accessibility/html/modal-dialog-in-iframe-closed-expected-android.txt
@@ -2,6 +2,6 @@
 ++android.view.View
 ++++android.view.View clickable name='Test for modal dialog closed in an iframe. '
 ++++android.view.View
-++++++android.view.View scrollable
+++++++android.view.View focusable scrollable
 ++++++++android.view.View
-++++++++++android.widget.Button role_description='button' clickable focusable name='I am a non-inert button!'
\ No newline at end of file
+++++++++++android.widget.Button role_description='button' clickable focusable name='I am a non-inert button!'
diff --git a/device/hid/hid_service_win.cc b/device/hid/hid_service_win.cc
index 0bfc485..8a20060 100644
--- a/device/hid/hid_service_win.cc
+++ b/device/hid/hid_service_win.cc
@@ -70,7 +70,8 @@
 
   task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(callback, new HidConnectionWin(device_info, std::move(file))));
+      base::Bind(callback, make_scoped_refptr(
+          new HidConnectionWin(device_info, std::move(file)))));
 }
 
 // static
diff --git a/docs/closure_compilation.md b/docs/closure_compilation.md
index 2c8fdcd..540abf6 100644
--- a/docs/closure_compilation.md
+++ b/docs/closure_compilation.md
@@ -5,6 +5,7 @@
 ### Pre-requisites
 
 You'll need Java 7 (preferably the OpenJDK version).  To install on Ubuntu:
+
 ```shell
 sudo apt-get install openjdk-7-jre
 ```
@@ -15,28 +16,33 @@
 ### Using ninja to compile the code
 
 We use GYP and ninja as our build system. To generate the ninja files from GYP:
+
 ```shell
-# notice the 2 in compiled_resources.gyp
+# notice the 2 in compiled_resources2.gyp
 GYP_GENERATORS=ninja tools/gyp/gyp --depth . third_party/closure_compiler/compiled_resources2.gyp
 ```
 
 To compile the JavaScript:
+
 ```shell
 ninja -C out/Default -j4
 ```
 
 The output should look something like this:
+
 ```shell
 ninja: Entering directory `out/Default/'
 [30/106] ACTION Compiling chrome/browser/resources/md_history/constants.js
 ```
 
 To generate and run the **deprecated** v1 gyp format, remove the "2" from "compiled_resources2.gyp":
+
 ```shell
 $ GYP_GENERATORS=ninja tools/gyp/gyp --depth . third_party/closure_compiler/compiled_resources.gyp
 ```
 
 Compiling works the same way for both v1 and v2 systems:
+
 ```shell
 ninja -C out/Default -j4
 ```
@@ -93,29 +99,23 @@
 
 In order to check that our code acts as we'd expect, we can create a
 
-    my_project/compiled_resources.gyp
+    my_project/compiled_resources2.gyp
 
 with the contents:
 
 ```
-# Copyright 2015 The Chromium Authors. All rights reserved.
+# Copyright 2016 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 {
   'targets': [
     {
       'target_name': 'my_file',  # file name without ".js"
-
-      'variables': {  # Only use if necessary (no need to specify empty lists).
-        'depends': [
-          'other_file.js',  # or 'other_project/compiled_resources.gyp:target',
-        ],
-        'externs': [
-          '<(CLOSURE_DIR)/externs/any_needed_externs.js'  # e.g. chrome.send(), chrome.app.window, etc.
-        ],
-      },
-
-      'includes': ['../third_party/closure_compiler/compile_js.gypi'],
+      'dependencies': [  # No need to specify empty lists.
+        '../compiled_resources2.gyp:other_file',
+        '<(EXTERNS_GYP):any_needed_externs'  # e.g. chrome.send(), chrome.app.window, etc.
+      ],
+      'includes': ['../third_party/closure_compiler/compile_js2.gypi'],
     },
   ],
 }
@@ -148,7 +148,7 @@
       'target_name': 'compile_all_resources',
       'dependencies': [
          # ... other projects ...
-++       '../my_project/compiled_resources.gyp:*',
+++       '../my_project/compiled_resources2.gyp:*',
       ],
     }
   ]
@@ -166,7 +166,7 @@
 map for use in debugging. In order to use the compiled JavaScript, we can create
 a
 
-    my_project/my_project_resources.gpy
+    my_project/my_project_resources.gyp
 
 with the contents:
 
@@ -219,6 +219,7 @@
 ```
 
 In your C++, the resource can be retrieved like this:
+
 ```
 base::string16 my_script =
     base::UTF8ToUTF16(
@@ -281,6 +282,7 @@
 ```
 
 with contents similar to this:
+
 ```
 # Copyright 2015 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
diff --git a/extensions/common/image_util.cc b/extensions/common/image_util.cc
index efad19b6..6a8e13a 100644
--- a/extensions/common/image_util.cc
+++ b/extensions/common/image_util.cc
@@ -13,6 +13,7 @@
 #include "base/strings/stringprintf.h"
 #include "third_party/re2/src/re2/re2.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "third_party/skia/include/utils/SkParse.h"
 #include "ui/gfx/color_utils.h"
 
 namespace extensions {
@@ -29,6 +30,11 @@
     NOTIMPLEMENTED();
     return false;
   }
+  if (SkParse::FindNamedColor(color_string.c_str(), color_string.size(),
+                              result) != nullptr) {
+    return true;
+  }
+
   return false;
 }
 
diff --git a/extensions/common/image_util_unittest.cc b/extensions/common/image_util_unittest.cc
index 8e7d80f8..e4a81bb4 100644
--- a/extensions/common/image_util_unittest.cc
+++ b/extensions/common/image_util_unittest.cc
@@ -108,4 +108,15 @@
   RunPassHslTest("hsla(0, 100%, 50%, 1)", SK_ColorRED);
 }
 
+TEST(ImageUtilTest, BasicColorKeyword) {
+  SkColor color = 0;
+  EXPECT_TRUE(image_util::ParseCssColorString("red", &color));
+  EXPECT_EQ(color, SK_ColorRED);
+
+  EXPECT_TRUE(image_util::ParseCssColorString("blue", &color));
+  EXPECT_EQ(color, SK_ColorBLUE);
+
+  EXPECT_FALSE(image_util::ParseCssColorString("my_red", &color));
+}
+
 }  // namespace extensions
diff --git a/extensions/common/permissions/base_set_operators.h b/extensions/common/permissions/base_set_operators.h
index 2ac5357..ffe0323 100644
--- a/extensions/common/permissions/base_set_operators.h
+++ b/extensions/common/permissions/base_set_operators.h
@@ -11,7 +11,6 @@
 #include <map>
 
 #include "base/memory/linked_ptr.h"
-#include "base/template_util.h"
 
 namespace extensions {
 
@@ -71,8 +70,8 @@
   BaseSetOperators() {
     // Ensure |T| is convertible to us, so we can safely downcast when calling
     // methods that must exist in |T|.
-    static_assert((base::is_convertible<T*, BaseSetOperators<T>*>::value),
-                   "U ptr must implicitly convert to T ptr");
+    static_assert(std::is_convertible<T*, BaseSetOperators<T>*>::value,
+                  "U ptr must implicitly convert to T ptr");
   }
 
   BaseSetOperators(const T& set) {
diff --git a/extensions/renderer/activity_log_converter_strategy_unittest.cc b/extensions/renderer/activity_log_converter_strategy_unittest.cc
index aa80447..9237cad 100644
--- a/extensions/renderer/activity_log_converter_strategy_unittest.cc
+++ b/extensions/renderer/activity_log_converter_strategy_unittest.cc
@@ -6,7 +6,6 @@
 #include "base/values.h"
 #include "extensions/renderer/activity_log_converter_strategy.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 using content::V8ValueConverter;
@@ -123,7 +122,6 @@
       "};"
       "})();";
 
-  blink::WebScopedMicrotaskSuppression microtasks_scope;
   v8::Local<v8::Script> script(
       v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
   v8::Local<v8::Object> v8_object = script->Run().As<v8::Object>();
diff --git a/extensions/renderer/api_test_base.cc b/extensions/renderer/api_test_base.cc
index 79f95e27..abf868b 100644
--- a/extensions/renderer/api_test_base.cc
+++ b/extensions/renderer/api_test_base.cc
@@ -214,7 +214,7 @@
 }
 
 void ApiTestEnvironment::RunPromisesAgain() {
-  v8::MicrotasksScope::PerformCheckpoint(env()->isolate());
+  env()->isolate()->RunMicrotasks();
   base::MessageLoop::current()->PostTask(
       FROM_HERE, base::Bind(&ApiTestEnvironment::RunPromisesAgain,
                             base::Unretained(this)));
diff --git a/extensions/renderer/module_system_test.cc b/extensions/renderer/module_system_test.cc
index 06a4d55..68c4bd1 100644
--- a/extensions/renderer/module_system_test.cc
+++ b/extensions/renderer/module_system_test.cc
@@ -253,7 +253,7 @@
 }
 
 void ModuleSystemTest::RunResolvedPromises() {
-  v8::MicrotasksScope::PerformCheckpoint(isolate_);
+  isolate_->RunMicrotasks();
 }
 
 }  // namespace extensions
diff --git a/extensions/renderer/safe_builtins.cc b/extensions/renderer/safe_builtins.cc
index 3a66eaf1..3bfa01a 100644
--- a/extensions/renderer/safe_builtins.cc
+++ b/extensions/renderer/safe_builtins.cc
@@ -9,7 +9,6 @@
 #include "base/strings/stringprintf.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/v8_helpers.h"
-#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 
 namespace extensions {
 
@@ -201,7 +200,6 @@
         return;
     }
 
-    blink::WebScopedMicrotaskSuppression microtasks_scope;
     v8::Local<v8::Value> return_value;
     if (function->Call(context, recv, argc, argv.get()).ToLocal(&return_value))
       info.GetReturnValue().Set(return_value);
diff --git a/gin/object_template_builder.h b/gin/object_template_builder.h
index 72369ee..bf0ece1 100644
--- a/gin/object_template_builder.h
+++ b/gin/object_template_builder.h
@@ -10,7 +10,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/strings/string_piece.h"
-#include "base/template_util.h"
 #include "gin/converter.h"
 #include "gin/function_template.h"
 #include "gin/gin_export.h"
@@ -57,7 +56,7 @@
 template <typename T>
 struct CallbackTraits<
     T,
-    typename std::enable_if<base::is_member_function_pointer<T>::value>::type> {
+    typename std::enable_if<std::is_member_function_pointer<T>::value>::type> {
   static v8::Local<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
                                                          T callback) {
     return CreateFunctionTemplate(isolate, base::Bind(callback),
diff --git a/gin/run_microtasks_observer.cc b/gin/run_microtasks_observer.cc
index 0ca0078..f453a66 100644
--- a/gin/run_microtasks_observer.cc
+++ b/gin/run_microtasks_observer.cc
@@ -15,7 +15,7 @@
 
 void RunMicrotasksObserver::DidProcessTask(const base::PendingTask& task) {
   v8::Isolate::Scope scope(isolate_);
-  v8::MicrotasksScope::PerformCheckpoint(isolate_);
+  isolate_->RunMicrotasks();
 }
 
 }  // namespace gin
diff --git a/gin/run_microtasks_observer.h b/gin/run_microtasks_observer.h
index ca160be..7f1431f 100644
--- a/gin/run_microtasks_observer.h
+++ b/gin/run_microtasks_observer.h
@@ -12,7 +12,7 @@
 
 // Runs any pending v8 Microtasks each time a task is completed.
 // TODO(hansmuller); At some point perhaps this can be replaced with
-// the (currently experimental) v8::MicrotasksPolicy::kAuto method.
+// the (currently experimental) Isolate::SetAutorunMicrotasks() method.
 
 class RunMicrotasksObserver : public base::MessageLoop::TaskObserver {
  public:
diff --git a/gin/wrappable.h b/gin/wrappable.h
index f253fd95..73c089a3 100644
--- a/gin/wrappable.h
+++ b/gin/wrappable.h
@@ -8,7 +8,6 @@
 #include <type_traits>
 
 #include "base/macros.h"
-#include "base/template_util.h"
 #include "gin/converter.h"
 #include "gin/gin_export.h"
 #include "gin/public/wrapper_info.h"
@@ -107,7 +106,7 @@
 template <typename T>
 struct Converter<T*,
                  typename std::enable_if<
-                     base::is_convertible<T*, WrappableBase*>::value>::type> {
+                     std::is_convertible<T*, WrappableBase*>::value>::type> {
   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
     return val->GetWrapper(isolate);
   }
diff --git a/google_apis/drive/test_util.h b/google_apis/drive/test_util.h
index f3fbf8d..96cf511 100644
--- a/google_apis/drive/test_util.h
+++ b/google_apis/drive/test_util.h
@@ -17,7 +17,6 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
-#include "base/template_util.h"
 #include "google_apis/drive/base_requests.h"
 #include "google_apis/drive/drive_api_error_codes.h"
 #include "google_apis/drive/task_util.h"
@@ -137,9 +136,9 @@
 
 // Declare if the type is movable or not. Currently limited to scoped_ptr only.
 // We can add more types upon the usage.
-template<typename T> struct IsMovable : base::false_type {};
+template<typename T> struct IsMovable : std::false_type {};
 template<typename T, typename D>
-struct IsMovable<scoped_ptr<T, D> > : base::true_type {};
+struct IsMovable<scoped_ptr<T, D> > : std::true_type {};
 
 // InType is const T& if |UseConstRef| is true, otherwise |T|.
 template<bool UseConstRef, typename T> struct InTypeHelper {
@@ -169,7 +168,7 @@
       //    |InType| is const T&.
       // 2) Otherwise, |T| as is.
     : InTypeHelper<
-          base::is_class<T>::value && !IsMovable<T>::value,  // UseConstRef
+          std::is_class<T>::value && !IsMovable<T>::value,  // UseConstRef
           T>,
       MoveHelper<IsMovable<T>::value, T> {
 };
diff --git a/gpu/command_buffer/service/gpu_preferences.h b/gpu/command_buffer/service/gpu_preferences.h
index 0c6a883..2721e27 100644
--- a/gpu/command_buffer/service/gpu_preferences.h
+++ b/gpu/command_buffer/service/gpu_preferences.h
@@ -66,10 +66,10 @@
   bool enforce_gl_minimums = false;
 
   // Sets the total amount of memory that may be allocated for GPU resources
-  size_t force_gpu_mem_available = 0;
+  uint32_t force_gpu_mem_available = 0;
 
   // Sets the maximum size of the in-memory gpu program cache, in kb
-  size_t gpu_program_cache_size = kDefaultMaxProgramCacheMemoryBytes;
+  uint32_t gpu_program_cache_size = kDefaultMaxProgramCacheMemoryBytes;
 
   // Disables the GPU shader on disk cache.
   bool disable_gpu_shader_disk_cache = false;
diff --git a/gpu/command_buffer/service/gpu_switches.cc b/gpu/command_buffer/service/gpu_switches.cc
index a02c484..389afcb 100644
--- a/gpu/command_buffer/service/gpu_switches.cc
+++ b/gpu/command_buffer/service/gpu_switches.cc
@@ -71,27 +71,4 @@
 // round intermediate values in ANGLE.
 const char kEmulateShaderPrecision[] = "emulate-shader-precision";
 
-const char* kGpuSwitches[] = {
-    kCompileShaderAlwaysSucceeds,
-    kDisableGLErrorLimit,
-    kDisableGLSLTranslator,
-    kDisableGpuDriverBugWorkarounds,
-    kDisableShaderNameHashing,
-    kEnableGPUCommandLogging,
-    kEnableGPUDebugging,
-    kEnableGPUServiceLoggingGPU,
-    kDisableGpuProgramCache,
-    kEnforceGLMinimums,
-    kForceGpuMemAvailableMb,
-    kGpuDriverBugWorkarounds,
-    kGpuProgramCacheSizeKb,
-    kDisableGpuShaderDiskCache,
-    kEnableShareGroupAsyncTextureUpload,
-    kEnableSubscribeUniformExtension,
-    kGLShaderIntermOutput,
-    kEmulateShaderPrecision,
-};
-
-const int kNumGpuSwitches = arraysize(kGpuSwitches);
-
 }  // namespace switches
diff --git a/gpu/command_buffer/service/gpu_switches.h b/gpu/command_buffer/service/gpu_switches.h
index ac6883a..5b50e0b 100644
--- a/gpu/command_buffer/service/gpu_switches.h
+++ b/gpu/command_buffer/service/gpu_switches.h
@@ -31,9 +31,6 @@
 GPU_EXPORT extern const char kGLShaderIntermOutput[];
 GPU_EXPORT extern const char kEmulateShaderPrecision[];
 
-GPU_EXPORT extern const char* kGpuSwitches[];
-GPU_EXPORT extern const int kNumGpuSwitches;
-
 }  // namespace switches
 
 #endif  // GPU_COMMAND_BUFFER_SERVICE_GPU_SWITCHES_H_
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc
index a7195b1b..157bb47 100644
--- a/gpu/config/gpu_driver_bug_list_json.cc
+++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@
 {
   "name": "gpu driver bug list",
   // Please update the version number whenever you change this file.
-  "version": "8.47",
+  "version": "8.48",
   "entries": [
     {
       "id": 1,
@@ -1780,6 +1780,21 @@
       "features": [
         "surface_texture_cant_detach"
       ]
+    },
+    {
+      "id": 149,
+      "description": "Direct composition flashes black initially on Win <10",
+      "cr_bugs": [588588],
+      "os": {
+        "type": "win",
+        "version": {
+          "op": "<",
+          "value": "10.0"
+        }
+      },
+      "features": [
+        "disable_direct_composition"
+      ]
     }
   ]
 }
diff --git a/ios/build/util/VERSION b/ios/build/util/VERSION
deleted file mode 100644
index f8c1610..0000000
--- a/ios/build/util/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-PATCH=0
diff --git a/ios/build/util/canary_version.py b/ios/build/util/canary_version.py
deleted file mode 100755
index 0992368..0000000
--- a/ios/build/util/canary_version.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-"""Writes canary version information to a specified file."""
-
-import datetime
-import sys
-import optparse
-import os
-
-
-def WriteIfChanged(file_name, content):
-  """
-  Write |content| to |file_name| iff the content is different from the
-  current content.
-  """
-  try:
-    old_content = open(file_name, 'rb').read()
-  except EnvironmentError:
-    pass
-  else:
-    if content == old_content:
-      return
-    os.unlink(file_name)
-  open(file_name, 'wb').write(content)
-
-
-def main(argv=None):
-  if argv is None:
-    argv = sys.argv
-
-  parser = optparse.OptionParser(usage="canary_version.py [options]")
-  parser.add_option("-o", "--output", metavar="FILE",
-                    help="write patch level to FILE")
-  opts, args = parser.parse_args(argv[1:])
-  out_file = opts.output
-
-  if args and out_file is None:
-    out_file = args.pop(0)
-
-  if args:
-    sys.stderr.write('Unexpected arguments: %r\n\n' % args)
-    parser.print_help()
-    sys.exit(2)
-
-  # Number of days since January 1st, 2012.
-  day_number = (datetime.date.today() - datetime.date(2012, 1, 1)).days
-  content = "PATCH={}\n".format(day_number)
-
-  if not out_file:
-    sys.stdout.write(content)
-  else:
-    WriteIfChanged(out_file, content)
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index f0ee057..84a5d34e 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -85,7 +85,11 @@
     "browser_state/off_the_record_chrome_browser_state_io_data.mm",
     "browser_state_metrics/browser_state_metrics.cc",
     "browser_state_metrics/browser_state_metrics.h",
-    "browsing_data_change_listening.h",
+    "browsing_data/browsing_data_change_listening.h",
+    "browsing_data/browsing_data_remover_helper.cc",
+    "browsing_data/browsing_data_remover_helper.h",
+    "browsing_data/ios_chrome_browsing_data_remover.h",
+    "browsing_data/ios_chrome_browsing_data_remover.mm",
     "chrome_constants.cc",
     "chrome_constants.h",
     "chrome_paths.h",
diff --git a/ios/chrome/browser/browsing_data_change_listening.h b/ios/chrome/browser/browsing_data/browsing_data_change_listening.h
similarity index 61%
rename from ios/chrome/browser/browsing_data_change_listening.h
rename to ios/chrome/browser/browsing_data/browsing_data_change_listening.h
index 2c0afe87..ca5284a 100644
--- a/ios/chrome/browser/browsing_data_change_listening.h
+++ b/ios/chrome/browser/browsing_data/browsing_data_change_listening.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 IOS_CHROME_BROWSER_BROWSING_DATA_CHANGE_LISTENING_H_
-#define IOS_CHROME_BROWSER_BROWSING_DATA_CHANGE_LISTENING_H_
+#ifndef IOS_CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_CHANGE_LISTENING_H_
+#define IOS_CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_CHANGE_LISTENING_H_
 
 // Listener for changes in browsing data.
 @protocol BrowsingDataChangeListening
@@ -11,4 +11,4 @@
 - (void)didChangeCookieStorage;
 @end
 
-#endif  // IOS_CHROME_BROWSER_BROWSING_DATA_CHANGE_LISTENING_H_
+#endif  // IOS_CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_CHANGE_LISTENING_H_
diff --git a/ios/chrome/browser/browsing_data/browsing_data_remover_helper.cc b/ios/chrome/browser/browsing_data/browsing_data_remover_helper.cc
new file mode 100644
index 0000000..3df5741
--- /dev/null
+++ b/ios/chrome/browser/browsing_data/browsing_data_remover_helper.cc
@@ -0,0 +1,98 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/chrome/browser/browsing_data/browsing_data_remover_helper.h"
+
+#include <utility>
+
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+
+BrowsingDataRemoverHelper::BrowsingDataRemoverHelper()
+    : current_remover_(nullptr) {}
+
+BrowsingDataRemoverHelper::~BrowsingDataRemoverHelper() {
+  DCHECK(pending_removals_.empty());
+}
+
+BrowsingDataRemoverHelper::BrowsingDataRemovalInfo::BrowsingDataRemovalInfo(
+    int remove_mask,
+    const base::Closure& callback)
+    : remove_mask(remove_mask) {
+  callbacks.push_back(callback);
+}
+
+BrowsingDataRemoverHelper::BrowsingDataRemovalInfo::~BrowsingDataRemovalInfo() {
+}
+
+void BrowsingDataRemoverHelper::Remove(ios::ChromeBrowserState* browser_state,
+                                       int remove_mask,
+                                       const base::Closure& callback) {
+  DCHECK(browser_state);
+  DCHECK(!browser_state->IsOffTheRecord());
+  // IOSChromeBrowsingDataRemover::Callbacks are called before
+  // OnIOSChromeBrowsingDataRemoverDone() and after
+  // IOSChromeBrowsingDataRemover::is_removing() is set to false. In this
+  // window, |current_remover_| needs to be checked as well.
+  if (current_remover_ || IOSChromeBrowsingDataRemover::is_removing()) {
+    // IOSChromeBrowsingDataRemover is not re-entrant. If it is already running,
+    // add the browser_state to |pending_removals_| for later deletion. If the
+    // browser_state is already scheduled for removal of browsing data, update
+    // the remove mask and callbacks.
+    DCHECK(current_remover_);
+    auto pending_removals_iter = pending_removals_.find(browser_state);
+    if (pending_removals_iter == pending_removals_.end()) {
+      scoped_ptr<BrowsingDataRemovalInfo> removal_info(
+          new BrowsingDataRemovalInfo(remove_mask, callback));
+      pending_removals_[browser_state] = std::move(removal_info);
+    } else {
+      pending_removals_iter->second->remove_mask |= remove_mask;
+      pending_removals_iter->second->callbacks.push_back(callback);
+    }
+  } else {
+    scoped_ptr<BrowsingDataRemovalInfo> removal_info(
+        new BrowsingDataRemovalInfo(remove_mask, callback));
+    DoRemove(browser_state, std::move(removal_info));
+  }
+}
+
+void BrowsingDataRemoverHelper::OnIOSChromeBrowsingDataRemoverDone() {
+  current_remover_ = nullptr;
+
+  DCHECK(current_removal_info_);
+  // Inform clients of the currently finished removal operation that browsing
+  // data was removed.
+  for (const auto& callback : current_removal_info_->callbacks) {
+    if (!callback.is_null()) {
+      callback.Run();
+    }
+  }
+  current_removal_info_.reset();
+
+  if (pending_removals_.empty())
+    return;
+
+  ios::ChromeBrowserState* next_browser_state =
+      pending_removals_.begin()->first;
+  scoped_ptr<BrowsingDataRemovalInfo> removal_info =
+      std::move(pending_removals_[next_browser_state]);
+  pending_removals_.erase(next_browser_state);
+  DoRemove(next_browser_state, std::move(removal_info));
+}
+
+void BrowsingDataRemoverHelper::DoRemove(
+    ios::ChromeBrowserState* browser_state,
+    scoped_ptr<BrowsingDataRemovalInfo> removal_info) {
+  DCHECK(!current_remover_ && !IOSChromeBrowsingDataRemover::is_removing());
+
+  current_removal_info_ = std::move(removal_info);
+
+  // IOSChromeBrowsingDataRemover deletes itself.
+  IOSChromeBrowsingDataRemover* remover =
+      IOSChromeBrowsingDataRemover::CreateForPeriod(
+          browser_state, IOSChromeBrowsingDataRemover::EVERYTHING);
+  remover->AddObserver(this);
+  current_remover_ = remover;
+  int remove_mask = current_removal_info_->remove_mask;
+  remover->Remove(remove_mask);
+}
diff --git a/ios/chrome/browser/browsing_data/browsing_data_remover_helper.h b/ios/chrome/browser/browsing_data/browsing_data_remover_helper.h
new file mode 100644
index 0000000..9ae632a
--- /dev/null
+++ b/ios/chrome/browser/browsing_data/browsing_data_remover_helper.h
@@ -0,0 +1,71 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_REMOVER_HELPER_H_
+#define IOS_CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_REMOVER_HELPER_H_
+
+#include <map>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "ios/chrome/browser/browsing_data/ios_chrome_browsing_data_remover.h"
+
+namespace ios {
+class ChromeBrowserState;
+}
+
+// A helper class that serializes execution of IOSChromeBrowsingDataRemover
+// methods since the IOSChromeBrowsingDataRemover APIs are not re-entrant.
+class BrowsingDataRemoverHelper
+    : public IOSChromeBrowsingDataRemover::Observer {
+ public:
+  BrowsingDataRemoverHelper();
+  ~BrowsingDataRemoverHelper() override;
+
+  // Removes the specified browsing data associated with |browser_state|. Calls
+  // |callback| when the browsing data is actually removed. |browser_state|
+  // cannot be null and must not be off the record.
+  // |callback| is called on the main thread.
+  // Note: Removal operations are not necessarily processed in the sequence that
+  // they are received in.
+  void Remove(ios::ChromeBrowserState* browser_state,
+              int remove_mask,
+              const base::Closure& callback);
+
+ private:
+  // Encapsulates the information that is needed to remove browsing data from
+  // a ChromeBrowserState.
+  struct BrowsingDataRemovalInfo {
+    // Creates a BrowsingDataRemovalInfo with a single callback |callback|.
+    BrowsingDataRemovalInfo(int remove_mask, const base::Closure& callback);
+    ~BrowsingDataRemovalInfo();
+    // The mask of all the types of browsing data that needs to be removed.
+    // Obtained from BrowsingDataRemoved::RemoveDataMask.
+    int remove_mask;
+    // The vector of callbacks that need to be run when browsing data is
+    // actually removed.
+    std::vector<base::Closure> callbacks;
+  };
+
+  // IOSChromeBrowsingDataRemover::Observer methods.
+  void OnIOSChromeBrowsingDataRemoverDone() override;
+
+  // Removes the browsing data using IOSChromeBrowsingDataRemover.
+  // IOSChromeBrowsingDataRemover
+  // must not be running.
+  void DoRemove(ios::ChromeBrowserState* browser_state,
+                scoped_ptr<BrowsingDataRemovalInfo> removal_info);
+
+  // A map that contains the all the ChromeBrowserStates that have a removal
+  // operation pending along with their associated BrowsingDataRemovalInfo.
+  std::map<ios::ChromeBrowserState*, scoped_ptr<BrowsingDataRemovalInfo>>
+      pending_removals_;
+  // The BrowsingDataRemovalInfo of the currently enqueued removal operation.
+  scoped_ptr<BrowsingDataRemovalInfo> current_removal_info_;
+  // The actual object that perfoms the removal of browsing data.
+  IOSChromeBrowsingDataRemover* current_remover_;
+};
+
+#endif  // IOS_CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_REMOVER_HELPER_H_
diff --git a/ios/chrome/browser/net/chrome_cookie_store_ios_client.mm b/ios/chrome/browser/net/chrome_cookie_store_ios_client.mm
index 9d0e74b..d3b8235 100644
--- a/ios/chrome/browser/net/chrome_cookie_store_ios_client.mm
+++ b/ios/chrome/browser/net/chrome_cookie_store_ios_client.mm
@@ -5,7 +5,7 @@
 #include "ios/chrome/browser/net/chrome_cookie_store_ios_client.h"
 
 #include "base/logging.h"
-#import "ios/chrome/browser/browsing_data_change_listening.h"
+#import "ios/chrome/browser/browsing_data/browsing_data_change_listening.h"
 #include "ios/web/public/web_thread.h"
 
 ChromeCookieStoreIOSClient::ChromeCookieStoreIOSClient(
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
index 4303c92cf..7b0b788 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.h
@@ -56,8 +56,8 @@
   bool IsOffTheRecord() const override;
   PrefService* GetPrefs() override;
   password_manager::PasswordStore* GetPasswordStore() const override;
-  void NotifyUserAutoSignin(
-      ScopedVector<autofill::PasswordForm> local_forms) override;
+  void NotifyUserAutoSignin(ScopedVector<autofill::PasswordForm> local_forms,
+                            const GURL& origin) override;
   void NotifyUserCouldBeAutoSignedIn(
       scoped_ptr<autofill::PasswordForm> form) override;
   void NotifySuccessfulLoginWithExistingPassword(
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
index 8fb509f..6566cdb4 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
@@ -98,7 +98,8 @@
 }
 
 void IOSChromePasswordManagerClient::NotifyUserAutoSignin(
-    ScopedVector<autofill::PasswordForm> local_forms) {}
+    ScopedVector<autofill::PasswordForm> local_forms,
+    const GURL& origin) {}
 
 void IOSChromePasswordManagerClient::NotifyUserCouldBeAutoSignedIn(
     scoped_ptr<autofill::PasswordForm> form) {}
diff --git a/ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.h b/ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.h
index baf891e..cf9117e 100644
--- a/ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.h
+++ b/ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.h
@@ -54,7 +54,7 @@
   scoped_ptr<password_manager::PasswordFormManager> form_to_save_;
 
   // Used to track the results we get from the info bar.
-  password_manager::metrics_util::ResponseType infobar_response_;
+  password_manager::metrics_util::UIDismissalReason infobar_response_;
 
   // Whether to show the password manager branded as Smart Lock.
   bool is_smart_lock_branding_enabled_;
diff --git a/ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.mm b/ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.mm
index 67da5c4..17a2ef2 100644
--- a/ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.mm
+++ b/ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.mm
@@ -39,16 +39,14 @@
 }
 
 IOSChromeSavePasswordInfoBarDelegate::~IOSChromeSavePasswordInfoBarDelegate() {
-  UMA_HISTOGRAM_ENUMERATION("PasswordManager.InfoBarResponse",
-                            infobar_response_,
-                            password_manager::metrics_util::NUM_RESPONSE_TYPES);
+  password_manager::metrics_util::LogUIDismissalReason(infobar_response_);
 }
 
 IOSChromeSavePasswordInfoBarDelegate::IOSChromeSavePasswordInfoBarDelegate(
     bool is_smart_lock_branding_enabled,
     scoped_ptr<PasswordFormManager> form_to_save)
     : form_to_save_(std::move(form_to_save)),
-      infobar_response_(password_manager::metrics_util::NO_RESPONSE),
+      infobar_response_(password_manager::metrics_util::NO_DIRECT_INTERACTION),
       is_smart_lock_branding_enabled_(is_smart_lock_branding_enabled) {}
 
 infobars::InfoBarDelegate::Type
@@ -86,14 +84,14 @@
 bool IOSChromeSavePasswordInfoBarDelegate::Accept() {
   DCHECK(form_to_save_);
   form_to_save_->Save();
-  infobar_response_ = password_manager::metrics_util::REMEMBER_PASSWORD;
+  infobar_response_ = password_manager::metrics_util::CLICKED_SAVE;
   return true;
 }
 
 bool IOSChromeSavePasswordInfoBarDelegate::Cancel() {
   DCHECK(form_to_save_);
   form_to_save_->PermanentlyBlacklist();
-  infobar_response_ = password_manager::metrics_util::NEVER_REMEMBER_PASSWORD;
+  infobar_response_ = password_manager::metrics_util::CLICKED_NEVER;
   return true;
 }
 
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp
index d6dd668..50d18a7 100644
--- a/ios/chrome/ios_chrome.gyp
+++ b/ios/chrome/ios_chrome.gyp
@@ -220,9 +220,11 @@
         'browser/browser_state/off_the_record_chrome_browser_state_io_data.mm',
         'browser/browser_state_metrics/browser_state_metrics.cc',
         'browser/browser_state_metrics/browser_state_metrics.h',
+        'browser/browsing_data/browsing_data_change_listening.h',
+        'browser/browsing_data/browsing_data_remover_helper.cc',
+        'browser/browsing_data/browsing_data_remover_helper.h',
         'browser/browsing_data/ios_chrome_browsing_data_remover.h',
         'browser/browsing_data/ios_chrome_browsing_data_remover.mm',
-        'browser/browsing_data_change_listening.h',
         'browser/chrome_constants.cc',
         'browser/chrome_constants.h',
         'browser/chrome_paths.h',
@@ -659,10 +661,10 @@
         'browser/variations/ios_chrome_variations_service_client.h',
         'browser/web/dom_altering_lock.h',
         'browser/web/dom_altering_lock.mm',
-        'browser/web/web_view_type_util.h',
-        'browser/web/web_view_type_util.mm',
         'browser/web/resubmit_data_controller.h',
         'browser/web/resubmit_data_controller.mm',
+        'browser/web/web_view_type_util.h',
+        'browser/web/web_view_type_util.mm',
         'browser/web_data_service_factory.cc',
         'browser/web_data_service_factory.h',
         'browser/web_resource/web_resource_util.cc',
diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h
index 38f428e..ea28d0c 100644
--- a/ipc/ipc_message_macros.h
+++ b/ipc/ipc_message_macros.h
@@ -249,7 +249,7 @@
 #define IPC_SYNC_MESSAGE_ROUTED(msg_class, in, out) \
   IPC_MESSAGE_DECL(msg_class, ROUTED, IPC_TUPLE in, IPC_TUPLE out)
 
-#define IPC_TUPLE(...) IPC::CheckedTuple<__VA_ARGS__>::Tuple
+#define IPC_TUPLE(...) std::tuple<__VA_ARGS__>
 
 #define IPC_MESSAGE_DECL(msg_name, kind, in_tuple, out_tuple)       \
   struct IPC_MESSAGE_EXPORT msg_name##_Meta {                       \
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
index 9369f023..d92d833 100644
--- a/ipc/ipc_message_utils.h
+++ b/ipc/ipc_message_utils.h
@@ -76,26 +76,12 @@
 struct NoParams {
 };
 
-// Specializations are checked by 'IPC checker' part of find-bad-constructs
-// Clang plugin (see WriteParam() below for the details).
-template <typename... Ts>
-struct CheckedTuple {
-  typedef std::tuple<Ts...> Tuple;
-};
-
 template <class P>
 static inline void GetParamSize(base::PickleSizer* sizer, const P& p) {
   typedef typename SimilarTypeTraits<P>::Type Type;
   ParamTraits<Type>::GetSize(sizer, static_cast<const Type&>(p));
 }
 
-// This function is checked by 'IPC checker' part of find-bad-constructs
-// Clang plugin to make it's not called on the following types:
-// 1. long / unsigned long (but not typedefs to)
-// 2. intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t,
-//    size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t,
-//    time_t, suseconds_t (including typedefs to)
-// 3. Any template referencing types above (e.g. std::vector<size_t>)
 template <class P>
 static inline void WriteParam(base::Pickle* m, const P& p) {
   typedef typename SimilarTypeTraits<P>::Type Type;
diff --git a/ipc/mojo/ipc_channel_mojo_unittest.cc b/ipc/mojo/ipc_channel_mojo_unittest.cc
index ac09ac3..615e72d 100644
--- a/ipc/mojo/ipc_channel_mojo_unittest.cc
+++ b/ipc/mojo/ipc_channel_mojo_unittest.cc
@@ -565,7 +565,13 @@
   RunTest(false);
 }
 
-TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
+// Times out on Android. crbug.com/593790
+#if defined(OS_ANDROID)
+#define MAYBE_SendFailAfterClose DISABLED_SendFailAfterClose
+#else
+#define MAYBE_SendFailAfterClose SendFailAfterClose
+#endif
+TEST_F(IPCChannelMojoTest, MAYBE_SendFailAfterClose) {
   InitWithMojo("IPCChannelMojoTestSendOkClient");
 
   ListenerThatExpectsOK listener;
diff --git a/ipc/mojo/ipc_mojo_bootstrap_unittest.cc b/ipc/mojo/ipc_mojo_bootstrap_unittest.cc
index 66ccdea..d702a6a 100644
--- a/ipc/mojo/ipc_mojo_bootstrap_unittest.cc
+++ b/ipc/mojo/ipc_mojo_bootstrap_unittest.cc
@@ -24,8 +24,9 @@
 
 namespace {
 
-class IPCMojoBootstrapTest : public mojo::edk::test::MojoTestBase {
+class IPCMojoBootstrapTest : public testing::Test {
  protected:
+  mojo::edk::test::MultiprocessTestHelper helper_;
 };
 
 class TestingDelegate : public IPC::MojoBootstrap::Delegate {
@@ -67,46 +68,34 @@
   base::MessageLoop message_loop;
   base::RunLoop run_loop;
   TestingDelegate delegate(run_loop.QuitClosure());
-  RUN_CHILD_ON_PIPE(IPCMojoBootstrapTestClient, pipe)
   scoped_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create(
-      mojo::MakeScopedHandle(mojo::MessagePipeHandle(pipe)),
+      helper_.StartChild("IPCMojoBootstrapTestClient"),
       IPC::Channel::MODE_SERVER, &delegate);
 
   bootstrap->Connect();
   run_loop.Run();
 
   EXPECT_TRUE(delegate.passed());
-  END_CHILD()
+  EXPECT_TRUE(helper_.WaitForChildTestShutdown());
 }
 
-class IPCMojoBootstrapTestClient {
-
-};
-
-}  // namespace
-
-namespace mojo {
-namespace edk {
-namespace {
-
 // A long running process that connects to us.
-DEFINE_TEST_CLIENT_TEST_WITH_PIPE(IPCMojoBootstrapTestClient,
-                                  IPCMojoBootstrapTest,
-                                  pipe) {
+MULTIPROCESS_TEST_MAIN_WITH_SETUP(
+    IPCMojoBootstrapTestClientTestChildMain,
+    ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) {
   base::MessageLoop message_loop;
   base::RunLoop run_loop;
   TestingDelegate delegate(run_loop.QuitClosure());
   scoped_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create(
-      mojo::MakeScopedHandle(mojo::MessagePipeHandle(pipe)),
+      mojo::edk::CreateChildMessagePipe(
+          mojo::edk::test::MultiprocessTestHelper::primordial_pipe_token),
       IPC::Channel::MODE_CLIENT, &delegate);
 
   bootstrap->Connect();
 
   run_loop.Run();
 
-  EXPECT_TRUE(delegate.passed());
+  return delegate.passed() ? 0 : 1;
 }
 
 }  // namespace
-}  // namespace edk
-}  // namespace mojo
diff --git a/mash/browser_driver/BUILD.gn b/mash/browser_driver/BUILD.gn
index b3cb7234..b1ad10b 100644
--- a/mash/browser_driver/BUILD.gn
+++ b/mash/browser_driver/BUILD.gn
@@ -16,7 +16,6 @@
   ]
 
   deps = [
-    ":manifest",
     "//base",
     "//components/mus/public/cpp",
     "//components/mus/public/interfaces",
@@ -24,6 +23,10 @@
     "//mojo/shell/public/cpp",
     "//mojo/shell/public/cpp:sources",
   ]
+
+  data_deps = [
+    ":manifest",
+  ]
 }
 
 mojo_application_manifest("manifest") {
diff --git a/mash/example/views_examples/BUILD.gn b/mash/example/views_examples/BUILD.gn
index 8de22c8c..9df0854 100644
--- a/mash/example/views_examples/BUILD.gn
+++ b/mash/example/views_examples/BUILD.gn
@@ -18,7 +18,6 @@
   ]
 
   deps = [
-    ":manifest",
     "//base",
     "//components/mus/public/interfaces",
     "//mojo/converters/geometry",
@@ -37,6 +36,7 @@
   resources = [ "$root_out_dir/views_mus_resources.pak" ]
 
   data_deps = [
+    ":manifest",
     "//components/mus",
   ]
 }
diff --git a/mash/example/window_type_launcher/BUILD.gn b/mash/example/window_type_launcher/BUILD.gn
index 4f89109..18d44e0 100644
--- a/mash/example/window_type_launcher/BUILD.gn
+++ b/mash/example/window_type_launcher/BUILD.gn
@@ -19,7 +19,6 @@
   ]
 
   deps = [
-    ":manifest",
     ":window_type_launcher_resources",
     "//base",
     "//base:base_static",
@@ -44,6 +43,7 @@
   ]
 
   data_deps = [
+    ":manifest",
     "//components/mus",
   ]
 }
diff --git a/mash/init/BUILD.gn b/mash/init/BUILD.gn
index adb69cd..1d79330d 100644
--- a/mash/init/BUILD.gn
+++ b/mash/init/BUILD.gn
@@ -17,7 +17,6 @@
   ]
 
   deps = [
-    ":manifest",
     "//base",
     "//components/mus/public/cpp",
     "//components/mus/public/interfaces",
@@ -26,6 +25,10 @@
     "//mojo/services/tracing/public/cpp",
     "//mojo/shell/public/cpp",
   ]
+
+  data_deps = [
+    ":manifest",
+  ]
 }
 
 mojo_application_manifest("manifest") {
diff --git a/mash/login/BUILD.gn b/mash/login/BUILD.gn
index e6ea919..f728171 100644
--- a/mash/login/BUILD.gn
+++ b/mash/login/BUILD.gn
@@ -17,7 +17,6 @@
   ]
 
   deps = [
-    ":manifest",
     "//base",
     "//components/mus/public/cpp",
     "//mash/init/public/interfaces",
@@ -32,6 +31,7 @@
   resources = [ "$root_out_dir/views_mus_resources.pak" ]
 
   data_deps = [
+    ":manifest",
     "//components/mus",
   ]
 }
diff --git a/mash/quick_launch/BUILD.gn b/mash/quick_launch/BUILD.gn
index b46475a4..64d18760 100644
--- a/mash/quick_launch/BUILD.gn
+++ b/mash/quick_launch/BUILD.gn
@@ -33,7 +33,6 @@
 
   deps = [
     ":lib",
-    ":manifest",
     "//mojo/shell/public/cpp",
     "//ui/views/mus:for_mojo_application",
   ]
@@ -41,6 +40,7 @@
   resources = [ "$root_out_dir/views_mus_resources.pak" ]
 
   data_deps = [
+    ":manifest",
     "//components/mus",
   ]
 }
diff --git a/mash/screenlock/BUILD.gn b/mash/screenlock/BUILD.gn
index 99bdf974..5463942 100644
--- a/mash/screenlock/BUILD.gn
+++ b/mash/screenlock/BUILD.gn
@@ -16,7 +16,6 @@
   ]
 
   deps = [
-    ":manifest",
     "//base",
     "//components/mus/public/cpp",
     "//mash/shell/public/interfaces",
@@ -33,6 +32,7 @@
   resources = [ "$root_out_dir/views_mus_resources.pak" ]
 
   data_deps = [
+    ":manifest",
     "//components/mus",
   ]
 }
diff --git a/mash/shell/BUILD.gn b/mash/shell/BUILD.gn
index 3f52946f..51b693dc 100644
--- a/mash/shell/BUILD.gn
+++ b/mash/shell/BUILD.gn
@@ -40,7 +40,6 @@
 
   deps = [
     ":lib",
-    ":manifest",
     "//base",
     "//mash/shell/public/interfaces",
     "//mojo/common",
@@ -48,6 +47,10 @@
     "//mojo/shell/public/cpp",
     "//mojo/shell/public/cpp:sources",
   ]
+
+  data_deps = [
+    ":manifest",
+  ]
 }
 
 mojo_application_manifest("manifest") {
diff --git a/mash/task_viewer/BUILD.gn b/mash/task_viewer/BUILD.gn
index 9f076ff..a4940dc 100644
--- a/mash/task_viewer/BUILD.gn
+++ b/mash/task_viewer/BUILD.gn
@@ -16,7 +16,6 @@
   ]
 
   deps = [
-    ":manifest",
     "//base",
     "//mojo/public/cpp/bindings",
     "//mojo/services/catalog/public/interfaces",
@@ -31,6 +30,7 @@
   resources = [ "$root_out_dir/views_mus_resources.pak" ]
 
   data_deps = [
+    ":manifest",
     "//components/mus",
   ]
 }
diff --git a/mash/wm/BUILD.gn b/mash/wm/BUILD.gn
index 39f95ec..8a71099 100644
--- a/mash/wm/BUILD.gn
+++ b/mash/wm/BUILD.gn
@@ -103,7 +103,6 @@
 
   deps = [
     ":lib",
-    ":manifest",
     ":resources",
     "//mojo/shell/public/cpp",
   ]
@@ -111,6 +110,7 @@
   # TODO(beng): This target relies on //mash/shell, but there is a cycle so we
   #             can't state that dependency here.
   data_deps = [
+    ":manifest",
     "//components/mus",
   ]
 
@@ -150,7 +150,6 @@
   ]
 
   deps = [
-    ":apptest_manifest",
     "//base",
     "//base/test:test_config",
     "//components/mus/public/cpp",
@@ -164,6 +163,7 @@
   ]
 
   data_deps = [
+    ":apptest_manifest",
     ":wm",
   ]
 
diff --git a/media/base/mac/BUILD.gn b/media/base/mac/BUILD.gn
index c1ebc9e..16ab29c2 100644
--- a/media/base/mac/BUILD.gn
+++ b/media/base/mac/BUILD.gn
@@ -21,6 +21,8 @@
       "avfoundation_glue.mm",
     ]
     libs = [
+      "AVFoundation.framework",
+
       # Required by video_frame_mac.cc.
       "CoreVideo.framework",
     ]
diff --git a/media/base/mac/avfoundation_glue.mm b/media/base/mac/avfoundation_glue.mm
index 543be6ce..297d4a4 100644
--- a/media/base/mac/avfoundation_glue.mm
+++ b/media/base/mac/avfoundation_glue.mm
@@ -4,6 +4,7 @@
 
 #import "media/base/mac/avfoundation_glue.h"
 
+#import <AVFoundation/AVFoundation.h>
 #include <dlfcn.h>
 #include <stddef.h>
 
@@ -15,8 +16,21 @@
 #include "base/trace_event/trace_event.h"
 #include "media/base/media_switches.h"
 
-namespace {
+// Forward declarations of AVFoundation.h strings.
+// This is needed to avoid compile time warnings since currently
+// |mac_deployment_target| is 10.6.
+extern NSString* const AVCaptureDeviceWasConnectedNotification;
+extern NSString* const AVCaptureDeviceWasDisconnectedNotification;
+extern NSString* const AVMediaTypeVideo;
+extern NSString* const AVMediaTypeAudio;
+extern NSString* const AVMediaTypeMuxed;
+extern NSString* const AVCaptureSessionRuntimeErrorNotification;
+extern NSString* const AVCaptureSessionDidStopRunningNotification;
+extern NSString* const AVCaptureSessionErrorKey;
+extern NSString* const AVVideoScalingModeKey;
+extern NSString* const AVVideoScalingModeResizeAspectFill;
 
+namespace {
 // Used for logging capture API usage. Classes are a partition. Elements in this
 // enum should not be deleted or rearranged; the only permitted operation is to
 // add new elements before CAPTURE_API_MAX, that must be equal to the last item.
@@ -44,37 +58,6 @@
   AVFoundationInternal() {
     bundle_ = [NSBundle
         bundleWithPath:@"/System/Library/Frameworks/AVFoundation.framework"];
-
-    const char* path = [[bundle_ executablePath] fileSystemRepresentation];
-    CHECK(path);
-    library_handle_ = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
-    CHECK(library_handle_) << dlerror();
-
-    struct {
-      NSString** loaded_string;
-      const char* symbol;
-    } av_strings[] = {
-        {&AVCaptureDeviceWasConnectedNotification_,
-         "AVCaptureDeviceWasConnectedNotification"},
-        {&AVCaptureDeviceWasDisconnectedNotification_,
-         "AVCaptureDeviceWasDisconnectedNotification"},
-        {&AVMediaTypeVideo_, "AVMediaTypeVideo"},
-        {&AVMediaTypeAudio_, "AVMediaTypeAudio"},
-        {&AVMediaTypeMuxed_, "AVMediaTypeMuxed"},
-        {&AVCaptureSessionRuntimeErrorNotification_,
-         "AVCaptureSessionRuntimeErrorNotification"},
-        {&AVCaptureSessionDidStopRunningNotification_,
-         "AVCaptureSessionDidStopRunningNotification"},
-        {&AVCaptureSessionErrorKey_, "AVCaptureSessionErrorKey"},
-        {&AVVideoScalingModeKey_, "AVVideoScalingModeKey"},
-        {&AVVideoScalingModeResizeAspectFill_,
-         "AVVideoScalingModeResizeAspectFill"},
-    };
-    for (auto& av_string : av_strings) {
-      *av_string.loaded_string = *reinterpret_cast<NSString**>(
-          dlsym(library_handle_, av_string.symbol));
-      CHECK(*av_string.loaded_string) << dlerror();
-    }
   }
 
   NSBundle* bundle() const { return bundle_; }
@@ -106,16 +89,21 @@
   NSBundle* bundle_;
   void* library_handle_;
   // The following members are replicas of the respectives in AVFoundation.
-  NSString* AVCaptureDeviceWasConnectedNotification_;
-  NSString* AVCaptureDeviceWasDisconnectedNotification_;
-  NSString* AVMediaTypeVideo_;
-  NSString* AVMediaTypeAudio_;
-  NSString* AVMediaTypeMuxed_;
-  NSString* AVCaptureSessionRuntimeErrorNotification_;
-  NSString* AVCaptureSessionDidStopRunningNotification_;
-  NSString* AVCaptureSessionErrorKey_;
-  NSString* AVVideoScalingModeKey_;
-  NSString* AVVideoScalingModeResizeAspectFill_;
+  NSString* AVCaptureDeviceWasConnectedNotification_ =
+      ::AVCaptureDeviceWasConnectedNotification;
+  NSString* AVCaptureDeviceWasDisconnectedNotification_ =
+      ::AVCaptureDeviceWasDisconnectedNotification;
+  NSString* AVMediaTypeVideo_ = ::AVMediaTypeVideo;
+  NSString* AVMediaTypeAudio_ = ::AVMediaTypeAudio;
+  NSString* AVMediaTypeMuxed_ = ::AVMediaTypeMuxed;
+  NSString* AVCaptureSessionRuntimeErrorNotification_ =
+      ::AVCaptureSessionRuntimeErrorNotification;
+  NSString* AVCaptureSessionDidStopRunningNotification_ =
+      ::AVCaptureSessionDidStopRunningNotification;
+  NSString* AVCaptureSessionErrorKey_ = ::AVCaptureSessionErrorKey;
+  NSString* AVVideoScalingModeKey_ = ::AVVideoScalingModeKey;
+  NSString* AVVideoScalingModeResizeAspectFill_ =
+      ::AVVideoScalingModeResizeAspectFill;
 
   DISALLOW_COPY_AND_ASSIGN(AVFoundationInternal);
 };
diff --git a/media/media.gyp b/media/media.gyp
index 071444aa..e7780ae 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -956,6 +956,7 @@
             'libraries': [
               '$(SDKROOT)/System/Library/Frameworks/AudioToolbox.framework',
               '$(SDKROOT)/System/Library/Frameworks/AudioUnit.framework',
+              '$(SDKROOT)/System/Library/Frameworks/AVFoundation.framework',
               '$(SDKROOT)/System/Library/Frameworks/CoreAudio.framework',
               '$(SDKROOT)/System/Library/Frameworks/CoreVideo.framework',
               '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn
index d0e4f9d7..7f13242 100644
--- a/media/mojo/services/BUILD.gn
+++ b/media/mojo/services/BUILD.gn
@@ -226,7 +226,6 @@
   ]
 
   deps = [
-    ":apptest_manifest",
     ":proxy",
     "//media/base:test_support",
     "//mojo/shell/public/cpp:test_support",
@@ -235,6 +234,7 @@
   ]
 
   data_deps = [
+    ":apptest_manifest",
     ":media",
   ]
 }
@@ -248,12 +248,12 @@
   testonly = true
 
   deps = [
-    ":pipeline_apptest_manifest",
     "//media/test:mojo_pipeline_integration_tests",
   ]
 
   data_deps = [
     ":media",
+    ":pipeline_apptest_manifest",
   ]
 }
 
diff --git a/media/renderers/skcanvas_video_renderer.cc b/media/renderers/skcanvas_video_renderer.cc
index d84f1529..0f51d55 100644
--- a/media/renderers/skcanvas_video_renderer.cc
+++ b/media/renderers/skcanvas_video_renderer.cc
@@ -227,10 +227,8 @@
     return true;
   }
 
-  bool onGetYUV8Planes(SkISize sizes[3],
-                       void* planes[3],
-                       size_t row_bytes[3],
-                       SkYUVColorSpace* color_space) override {
+  bool onQueryYUV8(SkYUVSizeInfo* sizeInfo,
+                   SkYUVColorSpace* color_space) const override {
     if (!media::IsYuvPlanar(frame_->format()) ||
         // TODO(rileya): Skia currently doesn't support YUVA conversion. Remove
         // this case once it does. As-is we will fall back on the pure-software
@@ -250,46 +248,61 @@
 
     for (int plane = VideoFrame::kYPlane; plane <= VideoFrame::kVPlane;
          ++plane) {
-      if (sizes) {
-        const gfx::Size size =
-            VideoFrame::PlaneSize(frame_->format(), plane,
-                                  gfx::Size(frame_->visible_rect().width(),
-                                            frame_->visible_rect().height()));
-        sizes[plane].set(size.width(), size.height());
-      }
-      if (row_bytes && planes) {
-        size_t offset;
-        const int y_shift =
-            (frame_->format() == media::PIXEL_FORMAT_YV16) ? 0 : 1;
-        if (plane == VideoFrame::kYPlane) {
-          offset = (frame_->stride(VideoFrame::kYPlane) *
-                    frame_->visible_rect().y()) +
-                   frame_->visible_rect().x();
-        } else {
-          offset = (frame_->stride(VideoFrame::kUPlane) *
-                    (frame_->visible_rect().y() >> y_shift)) +
-                   (frame_->visible_rect().x() >> 1);
-        }
+      const gfx::Size size = VideoFrame::PlaneSize(
+          frame_->format(), plane, gfx::Size(frame_->visible_rect().width(),
+                                             frame_->visible_rect().height()));
+      sizeInfo->fSizes[plane].set(size.width(), size.height());
+      sizeInfo->fWidthBytes[plane] = size.width();
+    }
 
-        // Copy the frame to the supplied memory.
-        // TODO: Find a way (API change?) to avoid this copy.
-        char* out_line = static_cast<char*>(planes[plane]);
-        int out_line_stride = row_bytes[plane];
-        uint8_t* in_line = frame_->data(plane) + offset;
-        int in_line_stride = frame_->stride(plane);
-        int plane_height = sizes[plane].height();
-        if (in_line_stride == out_line_stride) {
-          memcpy(out_line, in_line, plane_height * in_line_stride);
-        } else {
-          // Different line padding so need to copy one line at a time.
-          int bytes_to_copy_per_line = out_line_stride < in_line_stride
-                                           ? out_line_stride
-                                           : in_line_stride;
-          for (int line_no = 0; line_no < plane_height; line_no++) {
-            memcpy(out_line, in_line, bytes_to_copy_per_line);
-            in_line += in_line_stride;
-            out_line += out_line_stride;
-          }
+    return true;
+  }
+
+  bool onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo,
+                       void* planes[3]) override {
+    media::VideoPixelFormat format = frame_->format();
+    DCHECK(media::IsYuvPlanar(format) && format != PIXEL_FORMAT_YV12A);
+
+    for (int plane = VideoFrame::kYPlane; plane <= VideoFrame::kVPlane;
+         ++plane) {
+      const gfx::Size size = VideoFrame::PlaneSize(
+          frame_->format(), plane, gfx::Size(frame_->visible_rect().width(),
+                                             frame_->visible_rect().height()));
+      if (size.width() != sizeInfo.fSizes[plane].width() ||
+          size.height() != sizeInfo.fSizes[plane].height()) {
+        return false;
+      }
+
+      size_t offset;
+      const int y_shift =
+          (frame_->format() == media::PIXEL_FORMAT_YV16) ? 0 : 1;
+      if (plane == VideoFrame::kYPlane) {
+        offset =
+            (frame_->stride(VideoFrame::kYPlane) * frame_->visible_rect().y()) +
+            frame_->visible_rect().x();
+      } else {
+        offset = (frame_->stride(VideoFrame::kUPlane) *
+                  (frame_->visible_rect().y() >> y_shift)) +
+                 (frame_->visible_rect().x() >> 1);
+      }
+
+      // Copy the frame to the supplied memory.
+      // TODO: Find a way (API change?) to avoid this copy.
+      char* out_line = static_cast<char*>(planes[plane]);
+      int out_line_stride = sizeInfo.fWidthBytes[plane];
+      uint8_t* in_line = frame_->data(plane) + offset;
+      int in_line_stride = frame_->stride(plane);
+      int plane_height = sizeInfo.fSizes[plane].height();
+      if (in_line_stride == out_line_stride) {
+        memcpy(out_line, in_line, plane_height * in_line_stride);
+      } else {
+        // Different line padding so need to copy one line at a time.
+        int bytes_to_copy_per_line =
+            out_line_stride < in_line_stride ? out_line_stride : in_line_stride;
+        for (int line_no = 0; line_no < plane_height; line_no++) {
+          memcpy(out_line, in_line, bytes_to_copy_per_line);
+          in_line += in_line_stride;
+          out_line += out_line_stride;
         }
       }
     }
diff --git a/mojo/public/cpp/bindings/lib/shared_data.h b/mojo/public/cpp/bindings/lib/shared_data.h
index 0028e11..0afd892 100644
--- a/mojo/public/cpp/bindings/lib/shared_data.h
+++ b/mojo/public/cpp/bindings/lib/shared_data.h
@@ -5,8 +5,7 @@
 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_
 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_
 
-#include <assert.h>
-
+#include "base/logging.h"
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
 #include "mojo/public/cpp/system/macros.h"
@@ -83,11 +82,11 @@
     Holder(const T& value) : value(value), ref_count_(1) {}
 
     void Retain() {
-      assert(thread_checker_.CalledOnValidThread());
+      DCHECK(thread_checker_.CalledOnValidThread());
       ++ref_count_;
     }
     void Release() {
-      assert(thread_checker_.CalledOnValidThread());
+      DCHECK(thread_checker_.CalledOnValidThread());
       if (--ref_count_ == 0)
         delete this;
     }
diff --git a/mojo/public/cpp/bindings/strong_binding.h b/mojo/public/cpp/bindings/strong_binding.h
index 59ddb78..3694c68 100644
--- a/mojo/public/cpp/bindings/strong_binding.h
+++ b/mojo/public/cpp/bindings/strong_binding.h
@@ -5,9 +5,9 @@
 #ifndef MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
 #define MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
 
-#include <assert.h>
 #include <utility>
 
+#include "base/logging.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/callback.h"
 #include "mojo/public/cpp/bindings/interface_ptr.h"
@@ -71,19 +71,19 @@
   ~StrongBinding() {}
 
   void Bind(ScopedMessagePipeHandle handle) {
-    assert(!binding_.is_bound());
+    DCHECK(!binding_.is_bound());
     binding_.Bind(std::move(handle));
     binding_.set_connection_error_handler([this]() { OnConnectionError(); });
   }
 
   void Bind(InterfacePtr<Interface>* ptr) {
-    assert(!binding_.is_bound());
+    DCHECK(!binding_.is_bound());
     binding_.Bind(ptr);
     binding_.set_connection_error_handler([this]() { OnConnectionError(); });
   }
 
   void Bind(InterfaceRequest<Interface> request) {
-    assert(!binding_.is_bound());
+    DCHECK(!binding_.is_bound());
     binding_.Bind(std::move(request));
     binding_.set_connection_error_handler([this]() { OnConnectionError(); });
   }
@@ -97,7 +97,7 @@
   // This method may only be called after this StrongBinding has been bound to a
   // message pipe.
   void set_connection_error_handler(const Closure& error_handler) {
-    assert(binding_.is_bound());
+    DCHECK(binding_.is_bound());
     connection_error_handler_ = error_handler;
   }
 
diff --git a/mojo/public/cpp/system/buffer.h b/mojo/public/cpp/system/buffer.h
index a69fbaa..607aea1e1 100644
--- a/mojo/public/cpp/system/buffer.h
+++ b/mojo/public/cpp/system/buffer.h
@@ -12,10 +12,10 @@
 #ifndef MOJO_PUBLIC_CPP_SYSTEM_BUFFER_H_
 #define MOJO_PUBLIC_CPP_SYSTEM_BUFFER_H_
 
-#include <assert.h>
 #include <stdint.h>
 
 #include "base/compiler_specific.h"
+#include "base/logging.h"
 #include "mojo/public/c/system/buffer.h"
 #include "mojo/public/cpp/system/handle.h"
 #include "mojo/public/cpp/system/macros.h"
@@ -45,7 +45,7 @@
     const MojoCreateSharedBufferOptions* options,
     uint64_t num_bytes,
     ScopedSharedBufferHandle* shared_buffer) {
-  assert(shared_buffer);
+  DCHECK(shared_buffer);
   SharedBufferHandle handle;
   MojoResult rv =
       MojoCreateSharedBuffer(options, num_bytes, handle.mutable_value());
@@ -71,7 +71,7 @@
     BufferHandleType buffer,
     const MojoDuplicateBufferHandleOptions* options,
     ScopedHandleBase<BufferHandleType>* new_buffer) {
-  assert(new_buffer);
+  DCHECK(new_buffer);
   BufferHandleType handle;
   MojoResult rv = MojoDuplicateBufferHandle(
       buffer.value(), options, handle.mutable_value());
@@ -89,14 +89,14 @@
                             uint64_t num_bytes,
                             void** pointer,
                             MojoMapBufferFlags flags) {
-  assert(buffer.is_valid());
+  DCHECK(buffer.is_valid());
   return MojoMapBuffer(buffer.value(), offset, num_bytes, pointer, flags);
 }
 
 // Unmaps a part of a buffer that was previously mapped with |MapBuffer()|.
 // See |MojoUnmapBuffer()| for complete documentation.
 inline MojoResult UnmapBuffer(void* pointer) {
-  assert(pointer);
+  DCHECK(pointer);
   return MojoUnmapBuffer(pointer);
 }
 
@@ -115,7 +115,7 @@
 inline SharedBuffer::SharedBuffer(uint64_t num_bytes) {
   MojoResult result = CreateSharedBuffer(nullptr, num_bytes, &handle);
   ALLOW_UNUSED_LOCAL(result);
-  assert(result == MOJO_RESULT_OK);
+  DCHECK_EQ(MOJO_RESULT_OK, result);
 }
 
 inline SharedBuffer::SharedBuffer(
@@ -123,7 +123,7 @@
     const MojoCreateSharedBufferOptions& options) {
   MojoResult result = CreateSharedBuffer(&options, num_bytes, &handle);
   ALLOW_UNUSED_LOCAL(result);
-  assert(result == MOJO_RESULT_OK);
+  DCHECK_EQ(MOJO_RESULT_OK, result);
 }
 
 inline SharedBuffer::~SharedBuffer() {
diff --git a/mojo/public/cpp/system/data_pipe.h b/mojo/public/cpp/system/data_pipe.h
index e4c46dc..c5f9707 100644
--- a/mojo/public/cpp/system/data_pipe.h
+++ b/mojo/public/cpp/system/data_pipe.h
@@ -12,10 +12,10 @@
 #ifndef MOJO_PUBLIC_CPP_SYSTEM_DATA_PIPE_H_
 #define MOJO_PUBLIC_CPP_SYSTEM_DATA_PIPE_H_
 
-#include <assert.h>
 #include <stdint.h>
 
 #include "base/compiler_specific.h"
+#include "base/logging.h"
 #include "mojo/public/c/system/data_pipe.h"
 #include "mojo/public/cpp/system/handle.h"
 #include "mojo/public/cpp/system/macros.h"
@@ -64,8 +64,8 @@
     const MojoCreateDataPipeOptions* options,
     ScopedDataPipeProducerHandle* data_pipe_producer,
     ScopedDataPipeConsumerHandle* data_pipe_consumer) {
-  assert(data_pipe_producer);
-  assert(data_pipe_consumer);
+  DCHECK(data_pipe_producer);
+  DCHECK(data_pipe_consumer);
   DataPipeProducerHandle producer_handle;
   DataPipeConsumerHandle consumer_handle;
   MojoResult rv = MojoCreateDataPipe(options,
@@ -146,14 +146,14 @@
   MojoResult result =
       CreateDataPipe(nullptr, &producer_handle, &consumer_handle);
   ALLOW_UNUSED_LOCAL(result);
-  assert(result == MOJO_RESULT_OK);
+  DCHECK_EQ(MOJO_RESULT_OK, result);
 }
 
 inline DataPipe::DataPipe(const MojoCreateDataPipeOptions& options) {
   MojoResult result =
       CreateDataPipe(&options, &producer_handle, &consumer_handle);
   ALLOW_UNUSED_LOCAL(result);
-  assert(result == MOJO_RESULT_OK);
+  DCHECK_EQ(MOJO_RESULT_OK, result);
 }
 
 inline DataPipe::~DataPipe() {
diff --git a/mojo/public/cpp/system/handle.h b/mojo/public/cpp/system/handle.h
index 989d0c54..4df86af 100644
--- a/mojo/public/cpp/system/handle.h
+++ b/mojo/public/cpp/system/handle.h
@@ -5,11 +5,11 @@
 #ifndef MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_
 #define MOJO_PUBLIC_CPP_SYSTEM_HANDLE_H_
 
-#include <assert.h>
 #include <stdint.h>
 #include <limits>
 
 #include "base/compiler_specific.h"
+#include "base/logging.h"
 #include "base/macros.h"
 #include "base/move.h"
 #include "mojo/public/c/system/functions.h"
@@ -127,7 +127,7 @@
       return;
     MojoResult result = MojoClose(handle_.value());
     ALLOW_UNUSED_LOCAL(result);
-    assert(result == MOJO_RESULT_OK);
+    DCHECK_EQ(MOJO_RESULT_OK, result);
   }
 
   HandleType handle_;
diff --git a/mojo/public/cpp/system/message_pipe.h b/mojo/public/cpp/system/message_pipe.h
index b6201559..fab23e47 100644
--- a/mojo/public/cpp/system/message_pipe.h
+++ b/mojo/public/cpp/system/message_pipe.h
@@ -12,10 +12,10 @@
 #ifndef MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_
 #define MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_
 
-#include <assert.h>
 #include <stdint.h>
 
 #include "base/compiler_specific.h"
+#include "base/logging.h"
 #include "mojo/public/c/system/message_pipe.h"
 #include "mojo/public/cpp/system/handle.h"
 #include "mojo/public/cpp/system/macros.h"
@@ -44,8 +44,8 @@
 inline MojoResult CreateMessagePipe(const MojoCreateMessagePipeOptions* options,
                                     ScopedMessagePipeHandle* message_pipe0,
                                     ScopedMessagePipeHandle* message_pipe1) {
-  assert(message_pipe0);
-  assert(message_pipe1);
+  DCHECK(message_pipe0);
+  DCHECK(message_pipe1);
   MessagePipeHandle handle0;
   MessagePipeHandle handle1;
   MojoResult rv = MojoCreateMessagePipe(
@@ -103,14 +103,12 @@
 
 inline MessagePipe::MessagePipe() {
   MojoResult result = CreateMessagePipe(nullptr, &handle0, &handle1);
-  ALLOW_UNUSED_LOCAL(result);
-  assert(result == MOJO_RESULT_OK);
+  DCHECK_EQ(MOJO_RESULT_OK, result);
 }
 
 inline MessagePipe::MessagePipe(const MojoCreateMessagePipeOptions& options) {
   MojoResult result = CreateMessagePipe(&options, &handle0, &handle1);
-  ALLOW_UNUSED_LOCAL(result);
-  assert(result == MOJO_RESULT_OK);
+  DCHECK_EQ(MOJO_RESULT_OK, result);
 }
 
 inline MessagePipe::~MessagePipe() {
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
index 15124540..de7469c 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -3,6 +3,7 @@
 
 {%- set class_name = interface.name %}
 {%- set proxy_name = interface.name ~ "Proxy" %}
+{%- set namespace_as_string = "%s"|format(namespace|replace(".","::")) %}
 
 {%- macro alloc_params(struct, serialization_context) %}
   bool success = true;
@@ -34,7 +35,7 @@
 {%- endmacro %}
 
 {#--- Begin #}
-MOJO_STATIC_CONST_MEMBER_DEFINITION const char {{class_name}}::Name_[] = "{{namespace}}.{{class_name}}";
+MOJO_STATIC_CONST_MEMBER_DEFINITION const char {{class_name}}::Name_[] = "{{namespace_as_string}}::{{class_name}}";
 MOJO_STATIC_CONST_MEMBER_DEFINITION const uint32_t {{class_name}}::Version_;
 
 {#--- Constants #}
diff --git a/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl
index 6f80b04..527e15fb 100644
--- a/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl
@@ -59,7 +59,7 @@
         new {{manager_class(interface, True)}}() {
 
     public String getName() {
-        return "{{namespace}}.{{interface.name}}";
+        return "{{namespace|replace(".","::")}}::{{interface.name}}";
     }
 
     public int getVersion() {
diff --git a/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl
index 0f442b8..1b5cafa0 100644
--- a/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl
@@ -161,7 +161,7 @@
   }
 
   var {{interface.name}} = {
-    name: '{{namespace}}.{{interface.name}}',
+    name: '{{namespace|replace(".","::")}}::{{interface.name}}',
     proxyClass: {{interface.name}}Proxy,
     stubClass: {{interface.name}}Stub,
     validateRequest: validate{{interface.name}}Request,
diff --git a/mojo/services/catalog/BUILD.gn b/mojo/services/catalog/BUILD.gn
index 9dd285a..633f6d1 100644
--- a/mojo/services/catalog/BUILD.gn
+++ b/mojo/services/catalog/BUILD.gn
@@ -28,7 +28,6 @@
   ]
 
   deps = [
-    ":manifest",
     "//base",
     "//mojo/common:url_type_converters",
     "//mojo/services/catalog/public/interfaces",
@@ -36,6 +35,10 @@
     "//mojo/util:filename_util",
     "//net",
   ]
+
+  data_deps = [
+    ":manifest",
+  ]
 }
 
 mojo_application_manifest("manifest") {
diff --git a/mojo/services/tracing/BUILD.gn b/mojo/services/tracing/BUILD.gn
index d007fcf..6a417e7 100644
--- a/mojo/services/tracing/BUILD.gn
+++ b/mojo/services/tracing/BUILD.gn
@@ -14,10 +14,13 @@
 
   deps = [
     ":lib",
-    ":manifest",
     "//mojo/public/cpp/system",
     "//mojo/shell/public/cpp",
   ]
+
+  data_deps = [
+    ":manifest",
+  ]
 }
 
 mojo_application_manifest("manifest") {
diff --git a/mojo/shell/BUILD.gn b/mojo/shell/BUILD.gn
index 36e0b453..2f7be9d 100644
--- a/mojo/shell/BUILD.gn
+++ b/mojo/shell/BUILD.gn
@@ -34,7 +34,6 @@
   ]
 
   deps = [
-    ":manifest",
     "//base",
     "//base/third_party/dynamic_annotations",
     "//mojo/common",
@@ -51,6 +50,10 @@
     "//mojo/services/catalog:lib",
   ]
 
+  data_deps = [
+    ":manifest",
+  ]
+
   # For mojo/shell/application_loader.h
   allow_circular_includes_from = [ "//mojo/services/catalog:lib" ]
 }
diff --git a/mojo/shell/background/tests/BUILD.gn b/mojo/shell/background/tests/BUILD.gn
index d3b8b19..59b3482 100644
--- a/mojo/shell/background/tests/BUILD.gn
+++ b/mojo/shell/background/tests/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//mojo/public/mojo_application.gni")
-import("//mojo/public/mojo_application_manifest.gni")
 import("//mojo/public/tools/bindings/mojom.gni")
 import("//testing/test.gni")
 
diff --git a/mojo/shell/runner/child/BUILD.gn b/mojo/shell/runner/child/BUILD.gn
index a534dff8..6730d94 100644
--- a/mojo/shell/runner/child/BUILD.gn
+++ b/mojo/shell/runner/child/BUILD.gn
@@ -72,7 +72,6 @@
 
   deps = [
     ":apptest_interfaces",
-    ":manifest",
     "//base",
     "//base/test:test_config",
     "//mojo/shell/public/cpp:sources",
@@ -80,6 +79,7 @@
   ]
 
   data_deps = [
+    ":manifest",
     ":native_target",
   ]
 }
diff --git a/mojo/shell/tests/BUILD.gn b/mojo/shell/tests/BUILD.gn
index 91c2970..d044db42 100644
--- a/mojo/shell/tests/BUILD.gn
+++ b/mojo/shell/tests/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//mojo/public/mojo_application.gni")
-import("//mojo/public/mojo_application_manifest.gni")
 import("//mojo/public/tools/bindings/mojom.gni")
 import("//testing/test.gni")
 
diff --git a/mojo/shell/tests/connect/BUILD.gn b/mojo/shell/tests/connect/BUILD.gn
index d94fd9a1..d2818b2 100644
--- a/mojo/shell/tests/connect/BUILD.gn
+++ b/mojo/shell/tests/connect/BUILD.gn
@@ -14,7 +14,6 @@
   ]
   deps = [
     ":interfaces",
-    ":manifest",
     "//base",
     "//base/test:test_support",
     "//mojo/shell/public/cpp:shell_test_support",
@@ -25,6 +24,7 @@
   data_deps = [
     ":connect_test_app",
     ":connect_test_package",
+    ":manifest",
   ]
 }
 
diff --git a/mojo/shell/tests/connect/connect_unittests_manifest.json b/mojo/shell/tests/connect/connect_unittests_manifest.json
index a36e640..cb8e865 100644
--- a/mojo/shell/tests/connect/connect_unittests_manifest.json
+++ b/mojo/shell/tests/connect/connect_unittests_manifest.json
@@ -3,9 +3,9 @@
   "display_name": "Connect Unittests",
   "capabilities": {
     "mojo:connect_test_package": ["*"],
-    "mojo:connect_test_app": ["mojo.shell.test.mojom.ConnectTestService",
-                              "mojo.shell.test.mojom.StandaloneApp"],
-    "mojo:connect_test_a": ["mojo.shell.test.mojom.ConnectTestService",
-                            "mojo.shell.test.mojom.StandaloneApp"]
+    "mojo:connect_test_app": ["mojo::shell::test::mojom::ConnectTestService",
+                              "mojo::shell::test::mojom::StandaloneApp"],
+    "mojo:connect_test_a": ["mojo::shell::test::mojom::ConnectTestService",
+                            "mojo::shell::test::mojom::StandaloneApp"]
   }
 }
diff --git a/mojo/shell/tests/lifecycle/BUILD.gn b/mojo/shell/tests/lifecycle/BUILD.gn
index 302ba98..75753560 100644
--- a/mojo/shell/tests/lifecycle/BUILD.gn
+++ b/mojo/shell/tests/lifecycle/BUILD.gn
@@ -14,7 +14,6 @@
   ]
   deps = [
     ":interfaces",
-    ":manifest",
     "//base",
     "//base/test:test_support",
     "//mojo/edk/system",
@@ -28,6 +27,7 @@
     ":lifecycle_unittest_app",
     ":lifecycle_unittest_exe",
     ":lifecycle_unittest_package",
+    ":manifest",
   ]
 }
 
@@ -101,10 +101,13 @@
   deps = [
     ":app_client",
     ":interfaces",
-    ":lifecycle_unittest_app_manifest",
     "//base",
     "//mojo/shell/public/cpp:sources",
   ]
+
+  data_deps = [
+    ":lifecycle_unittest_app_manifest",
+  ]
 }
 
 mojo_application_manifest("lifecycle_unittest_app_manifest") {
@@ -119,11 +122,14 @@
   ]
   deps = [
     ":app_client",
-    ":lifecycle_unittest_exe_manifest",
     "//base",
     "//mojo/shell/public/cpp:sources",
     "//mojo/shell/runner/child:test_native_main",
   ]
+
+  data_deps = [
+    ":lifecycle_unittest_exe_manifest",
+  ]
 }
 
 mojo_application_manifest("lifecycle_unittest_exe_manifest") {
diff --git a/mojo/shell/tests/shell/BUILD.gn b/mojo/shell/tests/shell/BUILD.gn
index fc2c25a6..c1b2379 100644
--- a/mojo/shell/tests/shell/BUILD.gn
+++ b/mojo/shell/tests/shell/BUILD.gn
@@ -15,7 +15,6 @@
 
   deps = [
     ":interfaces",
-    ":manifest",
     "//base",
     "//base/test:test_config",
     "//mojo/common:common_base",
@@ -25,6 +24,7 @@
   ]
 
   data_deps = [
+    ":manifest",
     ":shell_unittest_driver",
     ":shell_unittest_target",
   ]
@@ -49,7 +49,6 @@
   ]
 
   deps = [
-    ":driver_manifest",
     ":interfaces",
     "//base",
     "//mojo/edk/system",
@@ -59,6 +58,10 @@
     "//mojo/shell/runner/child:test_native_main",
     "//mojo/shell/runner/common",
   ]
+
+  data_deps = [
+    ":driver_manifest",
+  ]
 }
 
 mojo_application_manifest("driver_manifest") {
@@ -76,11 +79,14 @@
 
   deps = [
     ":interfaces",
-    ":target_manifest",
     "//base",
     "//mojo/shell/public/cpp",
     "//mojo/shell/runner/child:test_native_main",
   ]
+
+  data_deps = [
+    ":target_manifest",
+  ]
 }
 
 mojo_application_manifest("target_manifest") {
diff --git a/mojo/shell/tests/shell/target_manifest.json b/mojo/shell/tests/shell/target_manifest.json
index f751592..68ddc21 100644
--- a/mojo/shell/tests/shell/target_manifest.json
+++ b/mojo/shell/tests/shell/target_manifest.json
@@ -1,5 +1,5 @@
 {
   "name": "exe:shell_unittest_target",
   "display_name": "Shell Unittest: Target",
-  "capabilities": { "mojo:shell_unittest": [ "mojo.shell.test.mojom.CreateInstanceTest" ] }
+  "capabilities": { "mojo:shell_unittest": [ "mojo::shell::test::mojom::CreateInstanceTest" ] }
 }
diff --git a/net/data/url_request_unittest/expect-ct-header.html b/net/data/url_request_unittest/expect-ct-header.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/net/data/url_request_unittest/expect-ct-header.html
diff --git a/net/data/url_request_unittest/expect-ct-header.html.mock-http-headers b/net/data/url_request_unittest/expect-ct-header.html.mock-http-headers
new file mode 100644
index 0000000..3e116582
--- /dev/null
+++ b/net/data/url_request_unittest/expect-ct-header.html.mock-http-headers
@@ -0,0 +1,4 @@
+HTTP/1.1 200 OK
+Cache-Control: private
+Content-Type: text/html; charset=ISO-8859-1
+Expect-CT: preload
diff --git a/net/docs/bug-triage-suggested-workflow.md b/net/docs/bug-triage-suggested-workflow.md
index 2d49cb34..a54d008 100644
--- a/net/docs/bug-triage-suggested-workflow.md
+++ b/net/docs/bug-triage-suggested-workflow.md
@@ -2,59 +2,6 @@
 
 [TOC]
 
-## Looking for new crashers
-
-1. Go to [go/chromecrash](https://goto.google.com/chromecrash).
-
-2. For each platform, look through the releases for which releases to
-   investigate.  As per bug-triage.txt, this should be the most recent canary,
-   the previous canary (if the most recent is less than a day old), and any of
-   dev/beta/stable that were released in the last couple of days.
-
-3. For each release, in the "Process Type" frame, click on "browser".
-
-4. At the bottom of the "Magic Signature" frame,  click "limit 1000".  Reported
-   crashers are sorted in decreasing order of the number of reports for that
-   crash signature.
-
-5. Search the page for *"net::"*.
-
-6. For each found signature:
-    * If there is a bug already filed, make sure it is correctly describing the
-      current bug (e.g. not closed, or not describing a long-past issue), and
-      make sure that if it is a *net* bug, that it is labeled as such.
-    * Ignore signatures that only occur once, as memory corruption can easily
-      cause one-off failures when the sample size is large enough.
-    * Ignore signatures that only come from a single client ID, as individual
-      machine malware and breakage can also easily cause one-off failures.
-    * Click on the number of reports field to see details of crash. Ignore it
-      if it doesn't appear to be a network bug.
-    * Otherwise, file a new bug directly from chromecrash.  Note that this may
-      result in filing bugs for low- and very-low- frequency crashes.  That's
-      ok; the bug tracker is a better tool to figure out whether or not we put
-      resources into those crashes than a snap judgement when filing bugs.
-    * For each bug you file, include the following information:
-        * The backtrace.  Note that the backtrace should not be added to the
-          bug if Restrict-View-Google isn't set on the bug as it may contain
-          PII.  Filing the bug from the crash reporter should do this
-          automatically, but check.
-        * The channel in which the bug is seen (canary/dev/beta/stable), its
-          frequency in that channel, and its rank among crashers in the
-          channel.
-        * The frequency of this signature in recent releases.  This information
-          is available by:
-            1. Clicking on the signature in the "Magic Signature" list
-            2. Clicking "Edit" on the dremel query at the top of the page
-            3. Removing the "product.version='X.Y.Z.W' AND" string and clicking
-               "Update".
-            4. Clicking "Limit 1000" in the Product Version list in the
-               resulting page (without this, the listing will be restricted to
-               the releases in which the signature is most common, which will
-               often not include the canary/dev release being investigated).
-            5. Choose some subset of that list, or all of it, to include in the
-               bug.  Make sure to indicate if there is a defined point in the
-               past before which the signature is not present.
-
 ## Identifying unlabeled network bugs on the tracker
 
 * Look at new uncomfirmed bugs since noon PST on the last triager's rotation.
@@ -72,8 +19,7 @@
   related.  Be sure to check if other bug reports have that stack trace, and
   mark as a dupe if so.  Even if the bug isn't network related, paste the stack
   trace in the bug, so no one else has to look up the crash stack from the ID.
-    * If there's no other information than the crash ID, ask for more details
-      and add the Needs-Feedback label.
+    * If there's just a blank form and a crash ID, just ignore the bug.
 
 * If network causes are possible, ask for a net-internals log (If it's not a
   browser crash) and attach the most specific internals-network label that's
@@ -96,11 +42,10 @@
 
 * Look through uncomfirmed and untriaged component=Internals>Network bugs,
   prioritizing those updated within the last week. [Use this issue tracker
-  query](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3DInternals%3ENetwork+-status%3AAssigned+-status%3AStarted+-status%3AAvailable&sort=-modified&colspec=ID+Pri+M+Stars+ReleaseBlock+Component+Status+Owner+Summary+OS+Modified&x=m&y=releaseblock&cells=ids).
+  query](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3DInternals%3ENetwork+status%3AUnconfirmed,Untriaged+-label:Needs-Feedback&sort=-modified).
 
 * If more information is needed from the reporter, ask for it and add the
-  Needs-Feedback label.  If the reporter has answered an earlier request for
-  information, remove that label.
+  Needs-Feedback label.
 
 * While investigating a new issue, change the status to Untriaged.
 
@@ -112,7 +57,8 @@
   mark it with component Privacy.
 
 * For bugs that already have a more specific network component, go ahead and
-  remove the Internals>Network component and move on.
+  remove the Internals>Network component to get them off the next triager's
+  radar and move on.
 
 * Try to figure out if it's really a network bug.  See common non-network
   components section for description of common components for issues incorrectly
@@ -161,14 +107,7 @@
   subcomponent applies, or only the Internals>Network>HTTP subcomponent
   applies, and there's no clear owner), try to figure out the exact cause.
 
-## Monitoring UMA histograms and Chirp/Gasper alerts
-
-Sign up to chrome-network-debugging@google.com mailing list to receive automated
-e-mails about UMA alerts.  Chirp is the new alert system, sending automated
-e-mails with sender address finch-chirp@google.com.  Gasper is the old alert
-system, sending automated e-mails with sender address gasper-alerts@google.com.
-While Chirp is of higher priority, Gasper is not deprecated yet, so both alerts
-should be monitored for the time being.
+## Investigate UMA notifications
 
 For each alert that fires, determine if it's a real alert and file a bug if so.
 
@@ -186,8 +125,56 @@
     * SimpleCache on Windows
     * DiskCache on Android.
 
-For each alert, respond to chrome-network-debugging@google.com with a summary of
-the action you've taken and why, including issue link if an issue was filed.
+## Looking for new crashers
+
+1. Go to [go/chromecrash](https://goto.google.com/chromecrash).
+
+2. For each platform, look through the releases for which releases to
+   investigate.  As per bug-triage.txt, this should be the most recent canary,
+   the previous canary (if the most recent is less than a day old), and any of
+   dev/beta/stable that were released in the last couple of days.
+
+3. For each release, in the "Process Type" frame, click on "browser".
+
+4. At the bottom of the "Magic Signature" frame,  click "limit 1000" (Or reduce
+   the limit to 100 first, as that's all the triager needs to look at).
+   Reported crashers are sorted in decreasing order of the number of reports for
+   that crash signature.
+
+5. Search the page for *"net::"*.
+
+6. For each found signature:
+    * Ignore signatures that only occur once or twice, as memory corruption can
+      easily cause one-off failures when the sample size is large enough.  Also
+      ignore crashers that are not in the top 100 for that platform / release.
+    * If there is a bug already filed, make sure it is correctly describing the
+      current bug (e.g. not closed, or not describing a long-past issue), and
+      make sure that if it is a *net* bug, that it is labeled as such.
+    * Ignore signatures that only come from one or two client IDs, as individual
+      machine malware and breakage can cause one-off failures.
+    * Click on the number of reports field to see details of crash. Ignore it
+      if it doesn't appear to be a network bug.
+    * Otherwise, file a new bug directly from chromecrash.
+    * For each bug you file, include the following information:
+        * The backtrace.  Note that the backtrace should not be added to the
+          bug if Restrict-View-Google isn't set on the bug as it may contain
+          PII.  Filing the bug from the crash reporter should do this
+          automatically, but check.
+        * The channel in which the bug is seen (canary/dev/beta/stable), and its
+          rank among crashers in the channel.
+        * The frequency of this signature in recent releases.  This information
+          is available by:
+            1. Clicking on the signature in the "Magic Signature" list
+            2. Clicking "Edit" on the dremel query at the top of the page
+            3. Removing the "product.version='X.Y.Z.W' AND" string and clicking
+               "Update".
+            4. Clicking "Limit 1000" in the Product Version list in the
+               resulting page (without this, the listing will be restricted to
+               the releases in which the signature is most common, which will
+               often not include the canary/dev release being investigated).
+            5. Choose some subset of that list, or all of it, to include in the
+               bug.  Make sure to indicate if there is a defined point in the
+               past before which the signature is not present.
 
 ## Investigating crashers
 
@@ -221,26 +208,3 @@
 
 * Load crash dumps, try to figure out a cause.  See
   http://www.chromium.org/developers/crash-reports for more information
-
-## Dealing with old bugs
-
-* For all network issues (Even those with owners, or a more specific component):
-
-    * If the issue has had the Needs-Feedback label for over a month, verify it
-      is waiting on feedback from the user.  If not, remove the label.
-      Otherwise, go ahead and mark the issue WontFix due to lack of response
-      and suggest the user file a new bug if the issue is still present. [Use
-      this issue tracker query for old Needs-Feedback
-      issues](https://code.google.com/p/chromium/issues/list?can=2&q=component%3AInternals>Network%20Needs=Feedback+modified-before%3Atoday-30&sort=-modified).
-
-    * If a bug is over 2 months old, and the underlying problem was never
-      reproduced or really understood:
-        * If it's over a year old, go ahead and mark the issue as Archived.
-        * Otherwise, ask reporters if the issue is still present, and attach
-          the Needs-Feedback label.
-
-* Old unconfirmed or untriaged Internals>Network issues can be investigated
-  just like newer ones.  Crashers should generally be given higher priority,
-  since we can verify if they still occur, and then newer issues, as they're
-  more likely to still be present, and more likely to have a still responsive
-  bug reporter.
diff --git a/net/docs/bug-triage.md b/net/docs/bug-triage.md
index 8a03d85..ac32403 100644
--- a/net/docs/bug-triage.md
+++ b/net/docs/bug-triage.md
@@ -6,16 +6,16 @@
 
 ## Responsibilities
 
-### Required:
-* Identify new crashers
-* Identify new network issues.
-* Request data about recent Internals>Network issue.
-* Investigate each recent Internals>Network issue.
-* Monitor UMA histograms and Chirp/Gasper alerts.
+### Required, in rough order of priority:
+* Identify new network bugs on the tracker.
+* Investigate UMA notifications.
+* Investigate recent Internals>Network issues with no subcomponent.
+* Follow up on Needs-Feedback issues for all network components.
+* Identify and file bugs for significant new crashers.
 
 ### Best effort:
-* Investigate unowned and owned-but-forgotten net/ crashers
-* Investigate old bugs
+* Investigate unowned and owned-but-forgotten net/ crashers.
+* Investigate old bugs.
 * Close obsolete bugs.
 
 All of the above is to be done on each rotation.  These responsibilities should
@@ -30,67 +30,104 @@
 
 ### Required:
 
-* Identify new crashers that are potentially network related.  You should check
-  the most recent canary, the previous canary (if the most recent less than a
-  day old), and any of dev/beta/stable that were released in the last couple of
-  days, for each platform.  File Internals>Network bugs on the tracker when
-  new crashers are found.
+* Identify new network bugs on the bug tracker.  All Unconfirmed issues filed
+  during your triage rotation should be scanned, and, for suspected network
+  bugs, a network component assigned and an about:net-internals log requested.
+  A triager is responsible for looking at bugs reported from noon PST / 3:00 pm
+  EST of the last day of the previous triager's rotation until the same time on
+  the last day of their rotation.  Once you've changed labels on a bug, mark it
+  Untriaged, so other triagers sorting through Unconfirmed bugs won't see it.
+  
+    * For desktop bugs, ask for a net-internals log and give the user a link to
+      https://sites.google.com/a/chromium.org/dev/for-testers/providing-network-details
+      (A link there appears on about:net-internals, for easy reference) for
+      instructions.  On mobile, point them to about:net-export.  In either case,
+      attach the Needs-Feedback label.
 
-* Identify new network bugs, both on the bug tracker and on the crash server.
-  All Unconfirmed issues filed during your triage rotation should be scanned,
-  and, for suspected network bugs, a network component assigned.  A triager is
-  responsible for looking at bugs reported from noon PST / 3:00 pm EST of the
-  last day of the previous triager's rotation until the same time on the last
-  day of their rotation.
+* Investigate UMA notifications.
 
-* Investigate each recent (new comment within the past week or so)
-  Internals>Network issue, driving getting information from reporters as
-  needed, until you can do one of the following:
+    * UMA notifications ("chirps") are alerts based on UMA histograms that are
+      sent to   chrome-network-debugging@google.com.  Triagers should subscribe
+      to this list.  When an alert fires, the triager should determine if the
+      alert looks to be real and file a bug with the appropriate label if so.
+      Note that if no label more specific than Internals>Network is appropriate,
+      the responsibility remains with the triager to continue investigating the
+      bug, as above.
+      
+    * The triager is responsible for looking at any notification previous
+      triagers did not, so when an issue is investigated, the person who did
+      so should respond to chrome-network-debugging@google.com with a short
+      email, describing their conclusions.  Future triagers can then use the
+      fact an alert was responded to as an inidicator of which of them need
+      to be followed up on.
+
+* Investigate [Uncomfirmed / Untriaged Internals>Network issues that don't
+  belong to a more specific network component](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3DInternals%3ENetwork+status%3AUnconfirmed,Untriaged+-label:Needs-Feedback&sort=-modified),
+  prioritizing the most recent issues, ones with the most responsive reporters,
+  and major crashers.  This will generally take up the majority of your time as
+  triager. Continue digging until you can do one of the following:
 
     * Mark it as *WontFix* (working as intended, obsolete issue) or a
       duplicate.
 
     * Mark it as a feature request.
 
+    * Mark it as Needs-Feedback.
+
     * Remove the Internals>Network component, replacing it with at least one
-      more specific network component or non-network component.  Promptly adding
-      non-network components when appropriate is important to get new bugs in front
-      of someone familiar with the relevant code, and to remove them from the
-      next triager's radar.  Because of the way the bug report wizard works, a
-      lot of bugs incorrectly end up with the network component.
+      more specific network component or non-network component. Replacing the
+      Internals>Network component gets it off the next triager's radar, and
+      in front of someone more familiar with the relevant code.  Note that
+      due to the way the bug report wizard works, a lot of bugs incorrectly end
+      up with the network component.
 
-    * The issue is assigned to an appropriate owner.
+    * The issue is assigned to an appropriate owner, and make sure to mark it
+      as "assigned" so the next triager doesn't run into it.
 
-    * If there is no more specific component for a bug, it should be investigated
-      until we have a good understanding of the cause of the problem, and some
-      idea how it should be fixed, at which point its status should be set to
-      Available.  Future triagers should ignore bugs with this status, unless
-      investigating stale bugs.
+    * If there is no more specific component for a bug, it should be
+      investigated by the triager until we have a good understanding of the
+      cause of the problem, and some idea how it should be fixed, at which point
+      its status should be set to Available.  Future triagers should ignore bugs
+      with this status, unless investigating stale bugs.
 
-* Monitor UMA histograms and Chirp/Gasper alerts.
+* Follow up on [Needs-Feedback issues for all components owned by the network
+  stack team](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3AInternals%3ENetwork%2CUI>Browser>Downloads+-component%3AInternals%3ENetwork%3EDataProxy+-component%3AInternals%3ENetwork%3EDataUse+-component%3AInternals%3ENetwork%3EVPN+Needs%3DFeedback).
 
-    * For each Chirp and Gasper alert that fires, the triager should determine
-      if the alert is real (not due to noise), and file a bug with the
-      appropriate component if so.  Note that if no component more specific than
-      Internals>Network is appropriate, the responsibility remains with the
-      triager to continue investigating the bug, as above.
+    * Remove label once feedback is provided.  Continue to investigate, if
+      the previous section applies.
+
+    * If the Needs-Feedback label has been present for one week, ping the
+      reporter.
+
+    * Archive after two weeks with no feedback, telling users to file a new
+      bug if they still have the issue, with the requested information, unless
+      the reporter indicates they'll provide data when they can.  In that case,
+      use your own judgment for further pings or archiving.
+
+* Identify significant new browser process
+  [crashers](https://goto.google.com/chromecrash) that are potentially network
+  related.  You should look at crashes for the most recent canary that has at
+  least a day of data, and if there's been a dev or beta release from the start
+  of the last triager's shift to the start of yours, you should also look at
+  that once it has at least a day of data.  Recent releases available
+  [here](https://omahaproxy.appspot.com/).  If both dev and beta have been
+  released in that period, just look at beta.  File Internals>Network bugs on
+  the tracker when new crashers are found.  Bugs  should only be filed for
+  crashes that are both in the top 100 for each release and occurred for more
+  than two users.
 
 ### Best Effort (As you have time):
 
+* Investigate old bugs, and bugs associated with Internals>Network
+  subcomponents.
+
 * Investigate unowned and owned but forgotten net/ crashers that are still
   occurring (As indicated by
   [go/chromecrash](https://goto.google.com/chromecrash)), prioritizing frequent
   and long standing crashers.
 
-* Investigate old bugs, prioritizing the most recent.
-
 * Close obsolete bugs.
 
-If you've investigated an issue (in code you don't normally work on) to an
-extent that you know how to fix it, and the fix is simple, feel free to take
-ownership of the issue and create a patch while on triage duty, but other tasks
-should take priority.
-
 See [bug-triage-suggested-workflow.md](bug-triage-suggested-workflow.md) for
 suggested workflows.
 
diff --git a/net/docs/crash-course-in-net-internals.md b/net/docs/crash-course-in-net-internals.md
index 5dcfb24..fa2094c 100644
--- a/net/docs/crash-course-in-net-internals.md
+++ b/net/docs/crash-course-in-net-internals.md
@@ -5,8 +5,8 @@
 document is aimed more at how to get started using some of its features to
 investigate bug reports, rather than as a feature overview.
 
-It would probably be useful to read [life-of-a-url-request.md](
-life-of-a-url-request.md) before this document.
+It would probably be useful to read
+[life-of-a-url-request.md](life-of-a-url-request.md) before this document.
 
 # What Data Net-Internals Contains
 
@@ -34,11 +34,12 @@
 
 The Event View shows events logged by the NetLog.  The NetLog model is that
 long-lived network stack objects, called sources, emit events over their
-lifetime.  Some events have a beginning and end point (during which other
-subevents may occur), and some only occur at a single point in time.  Generally
-only one event can be occuring for a source at a time.  If there can be multiple
-events doing completely independent thing, the code often uses new sources to
-represent the parallelism.
+lifetime.  When looking at the code, a "BoundNetLog" object contains a source
+ID, and a pointer to the NetLog the source emits events to.  Some events have a
+beginning and end point (during which other subevents may occur), and some only
+occur at a single point in time.  Generally only one event can be occuring for a
+source at a time.  If there can be multiple events doing completely independent
+thing, the code often uses new sources to represent the parallelism.
 
 "Sources" correspond to certain net objects, however, multiple layers of net/
 will often log to a single source.  Here are the main source types and what they
@@ -99,9 +100,8 @@
 an error of some sort (red background).  Cache errors are often non-fatal, so
 you should generally ignore those, and look for a more interesting one.
 
-* "type:URL_REQUEST sort:duration" will show the lonest-lived requests (as of
-when about:net-internals was opened) first.  This is often useful in finding
-hung or slow requests.
+* "type:URL_REQUEST sort:duration" will show the longest-lived requests first.
+This is often useful in finding hung or slow requests.
 
 For a list of other filter commands, you can mouse over the question mark on
 about:net-internals.
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index dc6fd93..1d44c5a 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -22,6 +22,7 @@
 #include "base/values.h"
 #include "crypto/sha2.h"
 #include "net/base/host_port_pair.h"
+#include "net/cert/ct_policy_status.h"
 #include "net/cert/x509_cert_types.h"
 #include "net/cert/x509_certificate.h"
 #include "net/dns/dns_util.h"
@@ -596,6 +597,7 @@
       report_sender_(nullptr),
       enable_static_pins_(true),
       enable_static_expect_ct_(true),
+      expect_ct_reporter_(nullptr),
       sent_reports_cache_(kMaxHPKPReportCacheEntries) {
 // Static pinning is only enabled for official builds to make sure that
 // others don't end up with pins that cannot be easily updated.
@@ -689,6 +691,12 @@
   report_sender_ = report_sender;
 }
 
+void TransportSecurityState::SetExpectCTReporter(
+    ExpectCTReporter* expect_ct_reporter) {
+  DCHECK(CalledOnValidThread());
+  expect_ct_reporter_ = expect_ct_reporter;
+}
+
 void TransportSecurityState::AddHSTSInternal(
     const std::string& host,
     TransportSecurityState::STSState::UpgradeMode upgrade_mode,
@@ -820,6 +828,27 @@
   return false;
 }
 
+bool TransportSecurityState::GetStaticExpectCTState(
+    const std::string& host,
+    ExpectCTState* expect_ct_state) const {
+  DCHECK(CalledOnValidThread());
+
+  if (!IsBuildTimely())
+    return false;
+
+  PreloadResult result;
+  if (!DecodeHSTSPreload(host, &result))
+    return false;
+
+  if (!enable_static_expect_ct_ || !result.expect_ct)
+    return false;
+
+  expect_ct_state->domain = host.substr(result.hostname_offset);
+  expect_ct_state->report_uri =
+      GURL(kExpectCTReportURIs[result.expect_ct_report_uri_id]);
+  return true;
+}
+
 bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
   DCHECK(CalledOnValidThread());
 
@@ -993,6 +1022,36 @@
   return true;
 }
 
+void TransportSecurityState::ProcessExpectCTHeader(
+    const std::string& value,
+    const HostPortPair& host_port_pair,
+    const SSLInfo& ssl_info) {
+  DCHECK(CalledOnValidThread());
+
+  if (!expect_ct_reporter_)
+    return;
+
+  if (value != "preload")
+    return;
+
+  if (!IsBuildTimely())
+    return;
+
+  if (!ssl_info.is_issued_by_known_root ||
+      !ssl_info.ct_compliance_details_available ||
+      ssl_info.ct_cert_policy_compliance ==
+          ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS) {
+    return;
+  }
+
+  ExpectCTState state;
+  if (!GetStaticExpectCTState(host_port_pair.host(), &state))
+    return;
+
+  expect_ct_reporter_->OnExpectCTFailed(host_port_pair, state.report_uri,
+                                        ssl_info);
+}
+
 // static
 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
   PreloadResult result;
@@ -1110,27 +1169,6 @@
   return kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts;
 }
 
-bool TransportSecurityState::GetStaticExpectCTState(
-    const std::string& host,
-    ExpectCTState* expect_ct_state) const {
-  DCHECK(CalledOnValidThread());
-
-  if (!IsBuildTimely())
-    return false;
-
-  PreloadResult result;
-  if (!DecodeHSTSPreload(host, &result))
-    return false;
-
-  if (!enable_static_expect_ct_ || !result.expect_ct)
-    return false;
-
-  expect_ct_state->domain = host.substr(result.hostname_offset);
-  expect_ct_state->report_uri =
-      GURL(kExpectCTReportURIs[result.expect_ct_report_uri_id]);
-  return true;
-}
-
 bool TransportSecurityState::GetDynamicSTSState(const std::string& host,
                                                 STSState* result) {
   DCHECK(CalledOnValidThread());
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h
index bb79c8e..a35e185 100644
--- a/net/http/transport_security_state.h
+++ b/net/http/transport_security_state.h
@@ -207,6 +207,22 @@
     virtual ~ReportSender() {}
   };
 
+  // An interface for building and asynchronously sending reports when a
+  // site expects valid Certificate Transparency information but it
+  // wasn't supplied.
+  class NET_EXPORT ExpectCTReporter {
+   public:
+    // Called when the host in |host_port_pair| has opted in to have
+    // reports about Expect CT policy violations sent to |report_uri|,
+    // and such a violation has occurred.
+    virtual void OnExpectCTFailed(const net::HostPortPair& host_port_pair,
+                                  const GURL& report_uri,
+                                  const net::SSLInfo& ssl_info) = 0;
+
+   protected:
+    virtual ~ExpectCTReporter() {}
+  };
+
   // Indicates whether or not a public key pin check should send a
   // report if a violation is detected.
   enum PublicKeyPinReportStatus { ENABLE_PIN_REPORTS, DISABLE_PIN_REPORTS };
@@ -238,6 +254,8 @@
 
   void SetReportSender(ReportSender* report_sender);
 
+  void SetExpectCTReporter(ExpectCTReporter* expect_ct_reporter);
+
   // Clears all dynamic data (e.g. HSTS and HPKP data).
   //
   // Does NOT persist changes using the Delegate, as this function is only
@@ -289,11 +307,6 @@
   // deployed.
   bool IsGooglePinnedHost(const std::string& host) const;
 
-  // Returns true and updates |*expect_ct_result| iff there is a static
-  // (built-in) state for |host| with expect_ct=true.
-  bool GetStaticExpectCTState(const std::string& host,
-                              ExpectCTState* expect_ct_result) const;
-
   // Returns true and updates |*result| iff |host| has HSTS (respectively, HPKP)
   // state. If multiple HSTS (respectively, HPKP) entries match |host|,  the
   // most specific match determines the HSTS (respectively, HPKP) return value.
@@ -337,6 +350,18 @@
                                    const HostPortPair& host_port_pair,
                                    const SSLInfo& ssl_info);
 
+  // Parses |value| as a Expect CT header value and sends an Expect CT
+  // report for |host_port_pair| if the following conditions are true:
+  // 1. The header value is "preload", indicating that the site wants to
+  // be opted in to Expect CT.
+  // 2. The given host is present on the Expect CT preload list with a
+  // valid report-uri, and the build is timely (i.e. preload list is fresh).
+  // 3. |ssl_info| indicates that the connection violated the Expect CT policy.
+  // 4. An Expect CT reporter has been provided with SetExpectCTReporter().
+  void ProcessExpectCTHeader(const std::string& value,
+                             const HostPortPair& host_port_pair,
+                             const SSLInfo& ssl_info);
+
   // The maximum number of seconds for which we'll cache an HSTS request.
   static const long int kMaxHSTSAgeSecs;
 
@@ -345,6 +370,7 @@
   FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, UpdateDynamicPKPOnly);
   FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, UpdateDynamicPKPMaxAge0);
   FRIEND_TEST_ALL_PREFIXES(HttpSecurityHeadersTest, NoClobberPins);
+  FRIEND_TEST_ALL_PREFIXES(URLRequestTestHTTP, ExpectCTHeader);
 
   typedef std::map<std::string, STSState> STSStateMap;
   typedef std::map<std::string, PKPState> PKPStateMap;
@@ -414,6 +440,11 @@
       const TransportSecurityState::PublicKeyPinReportStatus report_status,
       std::string* failure_log);
 
+  // Returns true and updates |*expect_ct_result| iff there is a static
+  // (built-in) state for |host| with expect_ct=true.
+  bool GetStaticExpectCTState(const std::string& host,
+                              ExpectCTState* expect_ct_result) const;
+
   // The sets of hosts that have enabled TransportSecurity. |domain| will always
   // be empty for a STSState or PKPState in these maps; the domain
   // comes from the map keys instead. In addition, |upgrade_mode| in the
@@ -432,6 +463,8 @@
   // True if static expect-CT state should be used.
   bool enable_static_expect_ct_;
 
+  ExpectCTReporter* expect_ct_reporter_;
+
   // Keeps track of reports that have been sent recently for
   // rate-limiting.
   ExpiringCache<std::string, bool, base::TimeTicks, std::less<base::TimeTicks>>
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index 75c7c75..c31f095 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -23,6 +23,7 @@
 #include "net/cert/asn1_util.h"
 #include "net/cert/cert_verifier.h"
 #include "net/cert/cert_verify_result.h"
+#include "net/cert/ct_policy_status.h"
 #include "net/cert/test_root_certs.h"
 #include "net/cert/x509_cert_types.h"
 #include "net/cert/x509_certificate.h"
@@ -46,6 +47,8 @@
 const char kSubdomain[] = "foo.example.test";
 const uint16_t kPort = 443;
 const char kReportUri[] = "http://report-example.test/test";
+const char kExpectCTStaticHostname[] = "preloaded-expect-ct.badssl.com";
+const char kExpectCTStaticReportURI[] = "https://report.badssl.com/expect-ct";
 
 // kGoodPath is blog.torproject.org.
 const char* const kGoodPath[] = {
@@ -100,6 +103,34 @@
   std::string latest_report_;
 };
 
+// A mock ExpectCTReporter that remembers the latest violation that was
+// reported and the number of violations reported.
+class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
+ public:
+  MockExpectCTReporter() : num_failures_(0) {}
+  ~MockExpectCTReporter() override {}
+
+  void OnExpectCTFailed(const HostPortPair& host_port_pair,
+                        const GURL& report_uri,
+                        const net::SSLInfo& ssl_info) override {
+    num_failures_++;
+    host_port_pair_ = host_port_pair;
+    report_uri_ = report_uri;
+    ssl_info_ = ssl_info;
+  }
+
+  const HostPortPair& host_port_pair() { return host_port_pair_; }
+  const GURL& report_uri() { return report_uri_; }
+  const SSLInfo& ssl_info() { return ssl_info_; }
+  uint32_t num_failures() { return num_failures_; }
+
+ private:
+  HostPortPair host_port_pair_;
+  GURL report_uri_;
+  SSLInfo ssl_info_;
+  uint32_t num_failures_;
+};
+
 void CompareCertificateChainWithList(
     const scoped_refptr<X509Certificate>& cert_chain,
     const base::ListValue* cert_list) {
@@ -210,6 +241,12 @@
                             TransportSecurityState::PKPState* pkp_result) {
     return state->GetStaticDomainState(host, sts_result, pkp_result);
   }
+
+  bool GetExpectCTState(TransportSecurityState* state,
+                        const std::string& host,
+                        TransportSecurityState::ExpectCTState* result) {
+    return state->GetStaticExpectCTState(host, result);
+  }
 };
 
 TEST_F(TransportSecurityStateTest, DomainNameOddities) {
@@ -1553,16 +1590,152 @@
 
 // Tests that static (preloaded) expect CT state is read correctly.
 TEST_F(TransportSecurityStateTest, PreloadedExpectCT) {
-  const char kHostname[] = "preloaded-expect-ct.badssl.com";
   TransportSecurityState state;
   TransportSecurityStateTest::EnableStaticExpectCT(&state);
   TransportSecurityState::ExpectCTState expect_ct_state;
-  EXPECT_TRUE(state.GetStaticExpectCTState(kHostname, &expect_ct_state));
-  EXPECT_EQ(kHostname, expect_ct_state.domain);
-  EXPECT_EQ(GURL("https://report.badssl.com/expect-ct"),
-            expect_ct_state.report_uri);
-  EXPECT_FALSE(state.GetStaticExpectCTState("pinning-test.badssl.com",
-                                            &expect_ct_state));
+  EXPECT_TRUE(
+      GetExpectCTState(&state, kExpectCTStaticHostname, &expect_ct_state));
+  EXPECT_EQ(kExpectCTStaticHostname, expect_ct_state.domain);
+  EXPECT_EQ(GURL(kExpectCTStaticReportURI), expect_ct_state.report_uri);
+  EXPECT_FALSE(
+      GetExpectCTState(&state, "pinning-test.badssl.com", &expect_ct_state));
+}
+
+// Tests that the Expect CT reporter is not notified for invalid or absent
+// header values.
+TEST_F(TransportSecurityStateTest, InvalidExpectCTHeader) {
+  HostPortPair host_port(kExpectCTStaticHostname, 443);
+  SSLInfo ssl_info;
+  ssl_info.ct_compliance_details_available = true;
+  ssl_info.ct_cert_policy_compliance =
+      ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+  ssl_info.is_issued_by_known_root = true;
+
+  TransportSecurityState state;
+  TransportSecurityStateTest::EnableStaticExpectCT(&state);
+  MockExpectCTReporter reporter;
+  state.SetExpectCTReporter(&reporter);
+  state.ProcessExpectCTHeader("", host_port, ssl_info);
+  EXPECT_EQ(0u, reporter.num_failures());
+
+  state.ProcessExpectCTHeader("blah blah", host_port, ssl_info);
+  EXPECT_EQ(0u, reporter.num_failures());
+
+  state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+  EXPECT_EQ(1u, reporter.num_failures());
+}
+
+// Tests that the Expect CT reporter is only notified about certificates
+// chaining to public roots.
+TEST_F(TransportSecurityStateTest, ExpectCTNonPublicRoot) {
+  HostPortPair host_port(kExpectCTStaticHostname, 443);
+  SSLInfo ssl_info;
+  ssl_info.ct_compliance_details_available = true;
+  ssl_info.ct_cert_policy_compliance =
+      ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+  ssl_info.is_issued_by_known_root = false;
+
+  TransportSecurityState state;
+  TransportSecurityStateTest::EnableStaticExpectCT(&state);
+  MockExpectCTReporter reporter;
+  state.SetExpectCTReporter(&reporter);
+  state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+  EXPECT_EQ(0u, reporter.num_failures());
+
+  ssl_info.is_issued_by_known_root = true;
+  state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+  EXPECT_EQ(1u, reporter.num_failures());
+}
+
+// Tests that the Expect CT reporter is not notified when compliance
+// details aren't available.
+TEST_F(TransportSecurityStateTest, ExpectCTComplianceNotAvailable) {
+  HostPortPair host_port(kExpectCTStaticHostname, 443);
+  SSLInfo ssl_info;
+  ssl_info.ct_compliance_details_available = false;
+  ssl_info.ct_cert_policy_compliance =
+      ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS;
+  ssl_info.is_issued_by_known_root = true;
+
+  TransportSecurityState state;
+  TransportSecurityStateTest::EnableStaticExpectCT(&state);
+  MockExpectCTReporter reporter;
+  state.SetExpectCTReporter(&reporter);
+  state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+  EXPECT_EQ(0u, reporter.num_failures());
+
+  ssl_info.ct_compliance_details_available = true;
+  state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+  EXPECT_EQ(1u, reporter.num_failures());
+}
+
+// Tests that the Expect CT reporter is not notified about compliant
+// connections.
+TEST_F(TransportSecurityStateTest, ExpectCTCompliantCert) {
+  HostPortPair host_port(kExpectCTStaticHostname, 443);
+  SSLInfo ssl_info;
+  ssl_info.ct_compliance_details_available = true;
+  ssl_info.ct_cert_policy_compliance =
+      ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS;
+  ssl_info.is_issued_by_known_root = true;
+
+  TransportSecurityState state;
+  TransportSecurityStateTest::EnableStaticExpectCT(&state);
+  MockExpectCTReporter reporter;
+  state.SetExpectCTReporter(&reporter);
+  state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+  EXPECT_EQ(0u, reporter.num_failures());
+
+  ssl_info.ct_cert_policy_compliance =
+      ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS;
+  state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+  EXPECT_EQ(1u, reporter.num_failures());
+}
+
+// Tests that the Expect CT reporter is not notified for a site that
+// isn't preloaded.
+TEST_F(TransportSecurityStateTest, ExpectCTNotPreloaded) {
+  HostPortPair host_port("not-expect-ct-preloaded.test", 443);
+  SSLInfo ssl_info;
+  ssl_info.ct_compliance_details_available = true;
+  ssl_info.ct_cert_policy_compliance =
+      ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS;
+  ssl_info.is_issued_by_known_root = true;
+
+  TransportSecurityState state;
+  TransportSecurityStateTest::EnableStaticExpectCT(&state);
+  MockExpectCTReporter reporter;
+  state.SetExpectCTReporter(&reporter);
+  state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+  EXPECT_EQ(0u, reporter.num_failures());
+
+  host_port.set_host(kExpectCTStaticHostname);
+  state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+  EXPECT_EQ(1u, reporter.num_failures());
+}
+
+// Tests that the Expect CT reporter is notified for noncompliant
+// connections.
+TEST_F(TransportSecurityStateTest, ExpectCTReporter) {
+  HostPortPair host_port(kExpectCTStaticHostname, 443);
+  SSLInfo ssl_info;
+  ssl_info.ct_compliance_details_available = true;
+  ssl_info.ct_cert_policy_compliance =
+      ct::CertPolicyCompliance::CERT_POLICY_NOT_DIVERSE_SCTS;
+  ssl_info.is_issued_by_known_root = true;
+
+  TransportSecurityState state;
+  TransportSecurityStateTest::EnableStaticExpectCT(&state);
+  MockExpectCTReporter reporter;
+  state.SetExpectCTReporter(&reporter);
+  state.ProcessExpectCTHeader("preload", host_port, ssl_info);
+  EXPECT_EQ(1u, reporter.num_failures());
+  EXPECT_TRUE(reporter.ssl_info().ct_compliance_details_available);
+  EXPECT_EQ(ssl_info.ct_cert_policy_compliance,
+            reporter.ssl_info().ct_cert_policy_compliance);
+  EXPECT_EQ(host_port.host(), reporter.host_port_pair().host());
+  EXPECT_EQ(host_port.port(), reporter.host_port_pair().port());
+  EXPECT_EQ(GURL(kExpectCTStaticReportURI), reporter.report_uri());
 }
 
 }  // namespace net
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index 1dd656e..a210022b0 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -2471,7 +2471,7 @@
              << old_peer_address.ToString() << " to "
              << peer_address_.ToString() << ", migrating connection.";
 
-    visitor_->OnConnectionMigration();
+    visitor_->OnConnectionMigration(peer_address_change_type);
     sent_packet_manager_.OnConnectionMigration(peer_address_change_type);
 
     return;
@@ -2487,7 +2487,7 @@
              << old_peer_address.ToString() << " to "
              << peer_address_.ToString() << ", migrating connection.";
 
-    visitor_->OnConnectionMigration();
+    visitor_->OnConnectionMigration(peer_address_change_type);
     DCHECK_NE(peer_address_change_type, NO_CHANGE);
     sent_packet_manager_.OnConnectionMigration(peer_address_change_type);
   }
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index df649b5..b9e9ef7 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -132,7 +132,7 @@
   virtual void OnCongestionWindowChange(QuicTime now) = 0;
 
   // Called when the connection receives a packet from a migrated client.
-  virtual void OnConnectionMigration() = 0;
+  virtual void OnConnectionMigration(PeerAddressChangeType type) = 0;
 
   // Called when the peer seems unreachable over the current path.
   virtual void OnPathDegrading() = 0;
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index 9774b5b..1b275cb 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -571,8 +571,10 @@
   QUIC_NETWORK_IDLE_TIMEOUT = 25,
   // The connection timed out waiting for the handshake to complete.
   QUIC_HANDSHAKE_TIMEOUT = 67,
-  // There was an error encountered migrating addresses
+  // There was an error encountered migrating addresses.
   QUIC_ERROR_MIGRATING_ADDRESS = 26,
+  // There was an error encountered migrating port only.
+  QUIC_ERROR_MIGRATING_PORT = 86,
   // There was an error while writing to the socket.
   QUIC_PACKET_WRITE_ERROR = 27,
   // There was an error while reading from the socket.
@@ -603,6 +605,8 @@
   QUIC_TIMEOUTS_WITH_OPEN_STREAMS = 74,
   // Closed because we failed to serialize a packet.
   QUIC_FAILED_TO_SERIALIZE_PACKET = 75,
+  // QUIC timed out after too many RTOs.
+  QUIC_TOO_MANY_RTOS = 85,
 
   // Crypto errors.
 
@@ -679,7 +683,7 @@
   QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM = 84,
 
   // No error. Used as bound while iterating.
-  QUIC_LAST_ERROR = 85,
+  QUIC_LAST_ERROR = 87,
 };
 
 // Must be updated any time a QuicErrorCode is deprecated.
diff --git a/net/quic/quic_session.h b/net/quic/quic_session.h
index 601edee..e0e3e809 100644
--- a/net/quic/quic_session.h
+++ b/net/quic/quic_session.h
@@ -76,7 +76,7 @@
   void OnSuccessfulVersionNegotiation(const QuicVersion& version) override;
   void OnCanWrite() override;
   void OnCongestionWindowChange(QuicTime /*now*/) override {}
-  void OnConnectionMigration() override {}
+  void OnConnectionMigration(PeerAddressChangeType type) override {}
   // Deletes streams that are safe to be deleted now that it's safe to do so (no
   // other operations are being done on the streams at this time).
   void PostProcessAfterData() override;
diff --git a/net/quic/quic_utils.cc b/net/quic/quic_utils.cc
index 03ca25db..d16bf72 100644
--- a/net/quic/quic_utils.cc
+++ b/net/quic/quic_utils.cc
@@ -262,6 +262,7 @@
     RETURN_STRING_LITERAL(QUIC_NETWORK_IDLE_TIMEOUT);
     RETURN_STRING_LITERAL(QUIC_HANDSHAKE_TIMEOUT);
     RETURN_STRING_LITERAL(QUIC_ERROR_MIGRATING_ADDRESS);
+    RETURN_STRING_LITERAL(QUIC_ERROR_MIGRATING_PORT);
     RETURN_STRING_LITERAL(QUIC_PACKET_WRITE_ERROR);
     RETURN_STRING_LITERAL(QUIC_PACKET_READ_ERROR);
     RETURN_STRING_LITERAL(QUIC_INVALID_STREAM_FRAME);
@@ -294,6 +295,7 @@
     RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES);
     RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
     RETURN_STRING_LITERAL(QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM);
+    RETURN_STRING_LITERAL(QUIC_TOO_MANY_RTOS);
     RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
     // Intentionally have no default case, so we'll break the build
     // if we add errors and don't put them here.
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index d29d667..e669b0c4 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -297,7 +297,7 @@
   MOCK_METHOD0(OnWriteBlocked, void());
   MOCK_METHOD0(OnCanWrite, void());
   MOCK_METHOD1(OnCongestionWindowChange, void(QuicTime now));
-  MOCK_METHOD0(OnConnectionMigration, void());
+  MOCK_METHOD1(OnConnectionMigration, void(PeerAddressChangeType type));
   MOCK_METHOD0(OnPathDegrading, void());
   MOCK_CONST_METHOD0(WillingAndAbleToWrite, bool());
   MOCK_CONST_METHOD0(HasPendingHandshake, bool());
diff --git a/net/socket/client_socket_pool.h b/net/socket/client_socket_pool.h
index 68946a8..73d90dd 100644
--- a/net/socket/client_socket_pool.h
+++ b/net/socket/client_socket_pool.h
@@ -11,7 +11,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/template_util.h"
 #include "base/time/time.h"
 #include "net/base/completion_callback.h"
 #include "net/base/load_states.h"
diff --git a/net/socket/client_socket_pool_manager_impl.h b/net/socket/client_socket_pool_manager_impl.h
index 538e507..e0662f19 100644
--- a/net/socket/client_socket_pool_manager_impl.h
+++ b/net/socket/client_socket_pool_manager_impl.h
@@ -6,12 +6,13 @@
 #define NET_SOCKET_CLIENT_SOCKET_POOL_MANAGER_IMPL_H_
 
 #include <map>
+#include <type_traits>
+
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/stl_util.h"
-#include "base/template_util.h"
 #include "base/threading/non_thread_safe.h"
 #include "net/cert/cert_database.h"
 #include "net/http/http_network_session.h"
@@ -39,7 +40,7 @@
 class OwnedPoolMap : public std::map<Key, Value> {
  public:
   OwnedPoolMap() {
-    static_assert(base::is_pointer<Value>::value, "value must be a pointer");
+    static_assert(std::is_pointer<Value>::value, "value must be a pointer");
   }
 
   ~OwnedPoolMap() {
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index 39a4a41b..ccc38d5 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -404,6 +404,7 @@
   // The ordering of these calls is not important.
   ProcessStrictTransportSecurityHeader();
   ProcessPublicKeyPinsHeader();
+  ProcessExpectCTHeader();
 
   // Handle the server notification of a new SDCH dictionary.
   SdchManager* sdch_manager(request()->context()->sdch_manager());
@@ -904,6 +905,28 @@
   }
 }
 
+void URLRequestHttpJob::ProcessExpectCTHeader() {
+  DCHECK(response_info_);
+  TransportSecurityState* security_state =
+      request_->context()->transport_security_state();
+  const SSLInfo& ssl_info = response_info_->ssl_info;
+
+  // Only accept Expect CT headers on HTTPS connections that have no
+  // certificate errors.
+  if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status) ||
+      !security_state) {
+    return;
+  }
+
+  // Only process the first Expect-CT header value.
+  HttpResponseHeaders* headers = GetResponseHeaders();
+  std::string value;
+  if (headers->EnumerateHeader(nullptr, "Expect-CT", &value)) {
+    security_state->ProcessExpectCTHeader(
+        value, HostPortPair::FromURL(request_info_.url), ssl_info);
+  }
+}
+
 void URLRequestHttpJob::OnStartCompleted(int result) {
   RecordTimer();
 
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h
index 56051fcc..c914ff1 100644
--- a/net/url_request/url_request_http_job.h
+++ b/net/url_request/url_request_http_job.h
@@ -98,6 +98,11 @@
   // Processes the Public-Key-Pins header, if one exists.
   void ProcessPublicKeyPinsHeader();
 
+  // Processes the Expect-CT header, if one exists. This header
+  // indicates that the server wants the user agent to send a report
+  // when a connection violates the Expect CT policy.
+  void ProcessExpectCTHeader();
+
   // |result| should be OK, or the request is canceled.
   void OnHeadersReceivedCallback(int result);
   void OnStartCompleted(int result);
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index c209b4b..330104b 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -16,6 +16,7 @@
 #include "base/threading/worker_pool.h"
 #include "net/base/host_port_pair.h"
 #include "net/cert/cert_verifier.h"
+#include "net/cert/ct_verifier.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/http/http_network_session.h"
 #include "net/http/http_response_headers.h"
@@ -50,18 +51,13 @@
 
 }  // namespace
 
-TestURLRequestContext::TestURLRequestContext()
-    : initialized_(false),
-      client_socket_factory_(nullptr),
-      proxy_delegate_(nullptr),
-      context_storage_(this) {
-  Init();
-}
+TestURLRequestContext::TestURLRequestContext() : TestURLRequestContext(false) {}
 
 TestURLRequestContext::TestURLRequestContext(bool delay_initialization)
     : initialized_(false),
       client_socket_factory_(nullptr),
       proxy_delegate_(nullptr),
+      ct_policy_enforcer_(nullptr),
       context_storage_(this) {
   if (!delay_initialization)
     Init();
@@ -108,6 +104,9 @@
     params.proxy_delegate = proxy_delegate();
     params.host_resolver = host_resolver();
     params.cert_verifier = cert_verifier();
+    params.cert_transparency_verifier = cert_transparency_verifier();
+    if (ct_policy_enforcer())
+      params.ct_policy_enforcer = ct_policy_enforcer();
     params.transport_security_state = transport_security_state();
     params.proxy_service = proxy_service();
     params.ssl_config_service = ssl_config_service();
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h
index 27fa9fcf..dc8d0e18 100644
--- a/net/url_request/url_request_test_util.h
+++ b/net/url_request/url_request_test_util.h
@@ -84,6 +84,11 @@
     context_storage_.set_sdch_manager(std::move(sdch_manager));
   }
 
+  CTPolicyEnforcer* ct_policy_enforcer() { return ct_policy_enforcer_; }
+  void set_ct_policy_enforcer(CTPolicyEnforcer* ct_policy_enforcer) {
+    ct_policy_enforcer_ = ct_policy_enforcer;
+  }
+
  private:
   bool initialized_;
 
@@ -97,6 +102,8 @@
 
   ProxyDelegate* proxy_delegate_;
 
+  CTPolicyEnforcer* ct_policy_enforcer_;
+
  protected:
   URLRequestContextStorage context_storage_;
 };
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 68e9997..a2da83a 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -59,6 +59,9 @@
 #include "net/base/upload_data_stream.h"
 #include "net/base/upload_file_element_reader.h"
 #include "net/base/url_util.h"
+#include "net/cert/ct_policy_status.h"
+#include "net/cert/ct_verifier.h"
+#include "net/cert/ct_verify_result.h"
 #include "net/cert/ev_root_ca_metadata.h"
 #include "net/cert/mock_cert_verifier.h"
 #include "net/cert/test_root_certs.h"
@@ -5888,6 +5891,7 @@
 #endif
 
 namespace {
+const char kExpectCTStaticHostname[] = "preloaded-expect-ct.badssl.com";
 const char kHPKPReportUri[] = "https://hpkp-report.test";
 }  // namespace
 
@@ -6239,6 +6243,124 @@
   EXPECT_FALSE(pkp_state.include_subdomains);
 }
 
+// An ExpectCTReporter that records the number of times OnExpectCTFailed() was
+// called.
+class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
+ public:
+  MockExpectCTReporter() : num_failures_(0) {}
+  ~MockExpectCTReporter() override {}
+
+  void OnExpectCTFailed(const HostPortPair& host_port_pair,
+                        const GURL& report_uri,
+                        const net::SSLInfo& ssl_info) override {
+    num_failures_++;
+  }
+
+  uint32_t num_failures() { return num_failures_; }
+
+ private:
+  uint32_t num_failures_;
+};
+
+// A CTVerifier that returns net::OK for every certificate.
+class MockCTVerifier : public CTVerifier {
+ public:
+  MockCTVerifier() {}
+  ~MockCTVerifier() override {}
+
+  int Verify(X509Certificate* cert,
+             const std::string& stapled_ocsp_response,
+             const std::string& sct_list_from_tls_extension,
+             ct::CTVerifyResult* result,
+             const BoundNetLog& net_log) override {
+    return net::OK;
+  }
+
+  void SetObserver(Observer* observer) override {}
+};
+
+// A CTPolicyEnforcer that returns a default CertPolicyCompliance value
+// for every certificate.
+class MockCTPolicyEnforcer : public CTPolicyEnforcer {
+ public:
+  MockCTPolicyEnforcer()
+      : default_result_(
+            ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS) {}
+  ~MockCTPolicyEnforcer() override {}
+
+  ct::CertPolicyCompliance DoesConformToCertPolicy(
+      X509Certificate* cert,
+      const SCTList& verified_scts,
+      const BoundNetLog& net_log) override {
+    return default_result_;
+  }
+
+  void set_default_result(ct::CertPolicyCompliance default_result) {
+    default_result_ = default_result;
+  }
+
+ private:
+  ct::CertPolicyCompliance default_result_;
+};
+
+// Tests that Expect CT headers are processed correctly.
+TEST_F(URLRequestTestHTTP, ExpectCTHeader) {
+  EmbeddedTestServer https_test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  https_test_server.SetSSLConfig(
+      net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN);
+  https_test_server.ServeFilesFromSourceDirectory(
+      base::FilePath(kTestFilePath));
+  ASSERT_TRUE(https_test_server.Start());
+
+  MockExpectCTReporter reporter;
+  TransportSecurityState transport_security_state;
+  transport_security_state.enable_static_expect_ct_ = true;
+  transport_security_state.SetExpectCTReporter(&reporter);
+
+  // Set up a MockCertVerifier to accept the certificate that the server sends.
+  scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate();
+  ASSERT_TRUE(cert);
+  MockCertVerifier cert_verifier;
+  CertVerifyResult verify_result;
+  verify_result.verified_cert = cert;
+  verify_result.is_issued_by_known_root = true;
+  cert_verifier.AddResultForCert(cert.get(), verify_result, OK);
+
+  // Set up a MockCTVerifier and MockCTPolicyEnforcer to trigger an Expect CT
+  // violation.
+  MockCTVerifier ct_verifier;
+  MockCTPolicyEnforcer ct_policy_enforcer;
+  ct_policy_enforcer.set_default_result(
+      ct::CertPolicyCompliance::CERT_POLICY_NOT_ENOUGH_SCTS);
+
+  TestNetworkDelegate network_delegate;
+  // Use a MockHostResolver (which by default maps all hosts to
+  // 127.0.0.1) so that the request can be sent to a site on the Expect
+  // CT preload list.
+  MockHostResolver host_resolver;
+  TestURLRequestContext context(true);
+  context.set_host_resolver(&host_resolver);
+  context.set_transport_security_state(&transport_security_state);
+  context.set_network_delegate(&network_delegate);
+  context.set_cert_verifier(&cert_verifier);
+  context.set_cert_transparency_verifier(&ct_verifier);
+  context.set_ct_policy_enforcer(&ct_policy_enforcer);
+  context.Init();
+
+  // Now send a request to trigger the violation.
+  TestDelegate d;
+  GURL url = https_test_server.GetURL("/expect-ct-header.html");
+  GURL::Replacements replace_host;
+  replace_host.SetHostStr(kExpectCTStaticHostname);
+  url = url.ReplaceComponents(replace_host);
+  scoped_ptr<URLRequest> violating_request(
+      context.CreateRequest(url, DEFAULT_PRIORITY, &d));
+  violating_request->Start();
+  base::RunLoop().Run();
+
+  EXPECT_EQ(1u, reporter.num_failures());
+}
+
 #endif  // !defined(OS_IOS)
 
 TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) {
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn
index 1415200..1d24f31 100644
--- a/remoting/protocol/BUILD.gn
+++ b/remoting/protocol/BUILD.gn
@@ -28,7 +28,6 @@
     "//remoting/base",
     "//remoting/codec",
     "//remoting/signaling",
-    "//third_party/boringssl",
     "//third_party/libyuv",
   ]
 
@@ -120,7 +119,6 @@
     "ppapi_module_stub.cc",
     "pseudotcp_adapter_unittest.cc",
     "session_config_unittest.cc",
-    "spake2_authenticator_unittest.cc",
     "ssl_hmac_channel_authenticator_unittest.cc",
     "third_party_authenticator_unittest.cc",
     "v2_authenticator_unittest.cc",
diff --git a/remoting/protocol/DEPS b/remoting/protocol/DEPS
index 20afa9ee..35a9c671 100644
--- a/remoting/protocol/DEPS
+++ b/remoting/protocol/DEPS
@@ -7,7 +7,6 @@
   "+ppapi/utility",
   "+remoting/codec",
   "+remoting/signaling",
-  "+third_party/boringssl",
   "+third_party/libjingle",
   "+third_party/webrtc",
   "+third_party/protobuf/src",
diff --git a/remoting/protocol/spake2_authenticator.cc b/remoting/protocol/spake2_authenticator.cc
deleted file mode 100644
index d7c0a6c..0000000
--- a/remoting/protocol/spake2_authenticator.cc
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "remoting/protocol/spake2_authenticator.h"
-
-#include <utility>
-
-#include "base/base64.h"
-#include "base/logging.h"
-#include "base/sys_byteorder.h"
-#include "crypto/hmac.h"
-#include "crypto/secure_util.h"
-#include "remoting/base/constants.h"
-#include "remoting/base/rsa_key_pair.h"
-#include "remoting/protocol/ssl_hmac_channel_authenticator.h"
-#include "third_party/boringssl/src/include/openssl/curve25519.h"
-#include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
-
-namespace remoting {
-namespace protocol {
-
-namespace {
-
-// Each peer sends 2 messages: <spake-message> and <verification-hash>. The
-// content of <spake-message> is the output of SPAKE2_generate_msg() and must
-// be passed to SPAKE2_process_msg() on the other end. This is enough to
-// generate authentication key. <verification-hash> is sent to confirm that both
-// ends get the same authentication key (which means they both know the
-// password). This verification hash is calculated in
-// CalculateVerificationHash() as follows:
-//    HMAC_SHA256(auth_key, ("host"|"client") + local_jid.length() + local_jid +
-//                remote_jid.length() + remote_jid)
-// where auth_key is the key produced by SPAKE2.
-
-const buzz::StaticQName kSpakeMessageTag = {kChromotingXmlNamespace,
-                                            "spake-message"};
-const buzz::StaticQName kVerificationHashTag = {kChromotingXmlNamespace,
-                                                "verification-hash"};
-const buzz::StaticQName kCertificateTag = {kChromotingXmlNamespace,
-                                           "certificate"};
-
-scoped_ptr<buzz::XmlElement> EncodeBinaryValueToXml(
-    const buzz::StaticQName& qname,
-    const std::string& content) {
-  std::string content_base64;
-  base::Base64Encode(content, &content_base64);
-
-  scoped_ptr<buzz::XmlElement> result(new buzz::XmlElement(qname));
-  result->SetBodyText(content_base64);
-  return result;
-}
-
-// Finds tag named |qname| in base_message and decodes it from base64 and stores
-// in |data|. If the element is not present then found is set to false otherwise
-// it's set to true. If the element is there and it's content cound't be decoded
-// then false is returned.
-bool DecodeBinaryValueFromXml(const buzz::XmlElement* message,
-                              const buzz::QName& qname,
-                              bool* found,
-                              std::string* data) {
-  const buzz::XmlElement* element = message->FirstNamed(qname);
-  *found = element != nullptr;
-  if (!*found)
-    return true;
-
-  if (!base::Base64Decode(element->BodyText(), data)) {
-    LOG(WARNING) << "Failed to parse " << qname.LocalPart();
-    return false;
-  }
-
-  return !data->empty();
-}
-
-std::string PrefixWithLength(const std::string& str) {
-  uint32_t length = base::HostToNet32(str.size());
-  return std::string(reinterpret_cast<char*>(&length), sizeof(length)) + str;
-}
-
-}  // namespace
-
-// static
-scoped_ptr<Authenticator> Spake2Authenticator::CreateForClient(
-    const std::string& local_id,
-    const std::string& remote_id,
-    const std::string& shared_secret,
-    Authenticator::State initial_state) {
-  return make_scoped_ptr(new Spake2Authenticator(
-      local_id, remote_id, shared_secret, false, initial_state));
-}
-
-// static
-scoped_ptr<Authenticator> Spake2Authenticator::CreateForHost(
-    const std::string& local_id,
-    const std::string& remote_id,
-    const std::string& shared_secret,
-    const std::string& local_cert,
-    scoped_refptr<RsaKeyPair> key_pair,
-    Authenticator::State initial_state) {
-  scoped_ptr<Spake2Authenticator> result(new Spake2Authenticator(
-      local_id, remote_id, shared_secret, true, initial_state));
-  result->local_cert_ = local_cert;
-  result->local_key_pair_ = key_pair;
-  return std::move(result);
-}
-
-Spake2Authenticator::Spake2Authenticator(const std::string& local_id,
-                                         const std::string& remote_id,
-                                         const std::string& shared_secret,
-                                         bool is_host,
-                                         Authenticator::State initial_state)
-    : local_id_(local_id),
-      remote_id_(remote_id),
-      shared_secret_(shared_secret),
-      is_host_(is_host),
-      state_(initial_state) {
-  spake2_context_ = SPAKE2_CTX_new(
-      is_host ? spake2_role_bob : spake2_role_alice,
-      reinterpret_cast<const uint8_t*>(local_id_.data()), local_id_.size(),
-      reinterpret_cast<const uint8_t*>(remote_id_.data()), remote_id_.size());
-
-  // Generate first message and push it to |pending_messages_|.
-  uint8_t message[SPAKE2_MAX_MSG_SIZE];
-  size_t message_size;
-  int result = SPAKE2_generate_msg(
-      spake2_context_, message, &message_size, sizeof(message),
-      reinterpret_cast<const uint8_t*>(shared_secret_.data()),
-      shared_secret_.size());
-  CHECK(result);
-  local_spake_message_.assign(reinterpret_cast<char*>(message), message_size);
-}
-
-Spake2Authenticator::~Spake2Authenticator() {
-  SPAKE2_CTX_free(spake2_context_);
-}
-
-Authenticator::State Spake2Authenticator::state() const {
-  if (state_ == ACCEPTED && !outgoing_verification_hash_.empty())
-    return MESSAGE_READY;
-  return state_;
-}
-
-bool Spake2Authenticator::started() const {
-  return started_;
-}
-
-Authenticator::RejectionReason Spake2Authenticator::rejection_reason() const {
-  DCHECK_EQ(state(), REJECTED);
-  return rejection_reason_;
-}
-
-void Spake2Authenticator::ProcessMessage(const buzz::XmlElement* message,
-                                         const base::Closure& resume_callback) {
-  ProcessMessageInternal(message);
-  resume_callback.Run();
-}
-
-void Spake2Authenticator::ProcessMessageInternal(
-    const buzz::XmlElement* message) {
-  DCHECK_EQ(state(), WAITING_MESSAGE);
-
-  // Parse the certificate.
-  bool cert_present;
-  if (!DecodeBinaryValueFromXml(message, kCertificateTag, &cert_present,
-                                &remote_cert_)) {
-    state_ = REJECTED;
-    rejection_reason_ = PROTOCOL_ERROR;
-    return;
-  }
-
-  // Client always expects certificate in the first message.
-  if (!is_host_ && remote_cert_.empty()) {
-    LOG(WARNING) << "No valid host certificate.";
-    state_ = REJECTED;
-    rejection_reason_ = PROTOCOL_ERROR;
-    return;
-  }
-
-  bool spake_message_present = false;
-  std::string spake_message;
-  bool verification_hash_present = false;
-  std::string verification_hash;
-  if (!DecodeBinaryValueFromXml(message, kSpakeMessageTag,
-                                &spake_message_present, &spake_message) ||
-      !DecodeBinaryValueFromXml(message, kVerificationHashTag,
-                                &verification_hash_present,
-                                &verification_hash)) {
-    state_ = REJECTED;
-    rejection_reason_ = PROTOCOL_ERROR;
-    return;
-  }
-
-  // |auth_key_| is generated when <spake-message> is received.
-  if (auth_key_.empty()) {
-    if (!spake_message_present) {
-      LOG(WARNING) << "<spake-message> not found.";
-      state_ = REJECTED;
-      rejection_reason_ = PROTOCOL_ERROR;
-      return;
-    }
-    uint8_t key[SPAKE2_MAX_KEY_SIZE];
-    size_t key_size;
-    started_ = true;
-    int result = SPAKE2_process_msg(
-        spake2_context_, key, &key_size, sizeof(key),
-        reinterpret_cast<const uint8_t*>(spake_message.data()),
-        spake_message.size());
-    if (!result) {
-      state_ = REJECTED;
-      rejection_reason_ = INVALID_CREDENTIALS;
-      return;
-    }
-    CHECK(key_size);
-    auth_key_.assign(reinterpret_cast<char*>(key), key_size);
-
-    outgoing_verification_hash_ =
-        CalculateVerificationHash(is_host_, local_id_, remote_id_);
-    expected_verification_hash_ =
-        CalculateVerificationHash(!is_host_, remote_id_, local_id_);
-  } else if (spake_message_present) {
-    LOG(WARNING) << "Received duplicate <spake-message>.";
-    state_ = REJECTED;
-    rejection_reason_ = PROTOCOL_ERROR;
-    return;
-  }
-
-  if (spake_message_sent_ && !verification_hash_present) {
-    LOG(WARNING) << "Didn't receive <verification-hash> when expected.";
-    state_ = REJECTED;
-    rejection_reason_ = PROTOCOL_ERROR;
-    return;
-  }
-
-  if (verification_hash_present) {
-    if (verification_hash.size() != expected_verification_hash_.size() ||
-        !crypto::SecureMemEqual(verification_hash.data(),
-                                expected_verification_hash_.data(),
-                                verification_hash.size())) {
-      state_ = REJECTED;
-      rejection_reason_ = INVALID_CREDENTIALS;
-      return;
-    }
-    state_ = ACCEPTED;
-    return;
-  }
-
-  state_ = MESSAGE_READY;
-}
-
-scoped_ptr<buzz::XmlElement> Spake2Authenticator::GetNextMessage() {
-  DCHECK_EQ(state(), MESSAGE_READY);
-
-  scoped_ptr<buzz::XmlElement> message = CreateEmptyAuthenticatorMessage();
-
-  if (!spake_message_sent_) {
-    if (!local_cert_.empty()) {
-      message->AddElement(
-          EncodeBinaryValueToXml(kCertificateTag, local_cert_).release());
-    }
-
-    message->AddElement(
-        EncodeBinaryValueToXml(kSpakeMessageTag, local_spake_message_)
-            .release());
-
-    spake_message_sent_ = true;
-  }
-
-  if (!outgoing_verification_hash_.empty()) {
-    message->AddElement(EncodeBinaryValueToXml(kVerificationHashTag,
-                                               outgoing_verification_hash_)
-                            .release());
-    outgoing_verification_hash_.clear();
-  }
-
-  if (state_ != ACCEPTED) {
-    state_ = WAITING_MESSAGE;
-  }
-  return message;
-}
-
-const std::string& Spake2Authenticator::GetAuthKey() const {
-  return auth_key_;
-}
-
-scoped_ptr<ChannelAuthenticator>
-Spake2Authenticator::CreateChannelAuthenticator() const {
-  DCHECK_EQ(state(), ACCEPTED);
-  CHECK(!auth_key_.empty());
-
-  if (is_host_) {
-    return SslHmacChannelAuthenticator::CreateForHost(
-        local_cert_, local_key_pair_, auth_key_);
-  } else {
-    return SslHmacChannelAuthenticator::CreateForClient(remote_cert_,
-                                                        auth_key_);
-  }
-}
-
-std::string Spake2Authenticator::CalculateVerificationHash(
-    bool from_host,
-    const std::string& local_id,
-    const std::string& remote_id) {
-  std::string message = (from_host ? "host" : "client") +
-                        PrefixWithLength(local_id) +
-                        PrefixWithLength(remote_id);
-  crypto::HMAC hmac(crypto::HMAC::SHA256);
-  std::string result(hmac.DigestLength(), '\0');
-  if (!hmac.Init(auth_key_) ||
-      !hmac.Sign(message, reinterpret_cast<uint8_t*>(&result[0]),
-                 result.length())) {
-    LOG(FATAL) << "Failed to calculate HMAC.";
-  }
-  return result;
-}
-
-}  // namespace protocol
-}  // namespace remoting
diff --git a/remoting/protocol/spake2_authenticator.h b/remoting/protocol/spake2_authenticator.h
deleted file mode 100644
index b16d634..0000000
--- a/remoting/protocol/spake2_authenticator.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef REMOTING_PROTOCOL_SPAKE2_AUTHENTICATOR_H_
-#define REMOTING_PROTOCOL_SPAKE2_AUTHENTICATOR_H_
-
-#include <queue>
-#include <string>
-
-#include "base/compiler_specific.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "remoting/protocol/authenticator.h"
-
-typedef struct spake2_ctx_st SPAKE2_CTX;
-
-namespace remoting {
-
-class RsaKeyPair;
-
-namespace protocol {
-
-// Authenticator that uses SPAKE2 implementation from BoringSSL. It
-// implements SPAKE2 over Curve25519.
-class Spake2Authenticator : public Authenticator {
- public:
-  static scoped_ptr<Authenticator> CreateForClient(
-      const std::string& local_id,
-      const std::string& remote_id,
-      const std::string& shared_secret,
-      State initial_state);
-
-  static scoped_ptr<Authenticator> CreateForHost(
-      const std::string& local_id,
-      const std::string& remote_id,
-      const std::string& shared_secret,
-      const std::string& local_cert,
-      scoped_refptr<RsaKeyPair> key_pair,
-      State initial_state);
-
-  ~Spake2Authenticator() override;
-
-  // Authenticator interface.
-  State state() const override;
-  bool started() const override;
-  RejectionReason rejection_reason() const override;
-  void ProcessMessage(const buzz::XmlElement* message,
-                      const base::Closure& resume_callback) override;
-  scoped_ptr<buzz::XmlElement> GetNextMessage() override;
-  const std::string& GetAuthKey() const override;
-  scoped_ptr<ChannelAuthenticator> CreateChannelAuthenticator() const override;
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(Spake2AuthenticatorTest, InvalidSecret);
-
-  Spake2Authenticator(const std::string& local_id,
-                      const std::string& remote_id,
-                      const std::string& shared_secret,
-                      bool is_host,
-                      State initial_state);
-
-  virtual void ProcessMessageInternal(const buzz::XmlElement* message);
-
-  std::string CalculateVerificationHash(bool from_host,
-                                        const std::string& local_id,
-                                        const std::string& remote_id);
-
-  const std::string local_id_;
-  const std::string remote_id_;
-  const std::string shared_secret_;
-  const bool is_host_;
-
-  // Used only for host authenticators.
-  std::string local_cert_;
-  scoped_refptr<RsaKeyPair> local_key_pair_;
-
-  // Used only for client authenticators.
-  std::string remote_cert_;
-
-  // Used for both host and client authenticators.
-  SPAKE2_CTX* spake2_context_;
-  State state_;
-  bool started_ = false;
-  RejectionReason rejection_reason_ = INVALID_CREDENTIALS;
-  std::string local_spake_message_;
-  bool spake_message_sent_ = false;
-  std::string outgoing_verification_hash_;
-  std::string auth_key_;
-  std::string expected_verification_hash_;
-
-  DISALLOW_COPY_AND_ASSIGN(Spake2Authenticator);
-};
-
-}  // namespace protocol
-}  // namespace remoting
-
-#endif  // REMOTING_PROTOCOL_SPAKE2_AUTHENTICATOR_H_
diff --git a/remoting/protocol/spake2_authenticator_unittest.cc b/remoting/protocol/spake2_authenticator_unittest.cc
deleted file mode 100644
index 9f5e5d0..0000000
--- a/remoting/protocol/spake2_authenticator_unittest.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "remoting/protocol/spake2_authenticator.h"
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "remoting/base/rsa_key_pair.h"
-#include "remoting/protocol/authenticator_test_base.h"
-#include "remoting/protocol/channel_authenticator.h"
-#include "remoting/protocol/connection_tester.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
-
-using testing::_;
-using testing::DeleteArg;
-using testing::SaveArg;
-
-namespace remoting {
-namespace protocol {
-
-namespace {
-
-const int kMessageSize = 100;
-const int kMessages = 1;
-
-const char kClientId[] = "alice@gmail.com/abc";
-const char kHostId[] = "alice@gmail.com/123";
-
-const char kTestSharedSecret[] = "1234-1234-5678";
-const char kTestSharedSecretBad[] = "0000-0000-0001";
-
-}  // namespace
-
-class Spake2AuthenticatorTest : public AuthenticatorTestBase {
- public:
-  Spake2AuthenticatorTest() {}
-  ~Spake2AuthenticatorTest() override {}
-
- protected:
-  void InitAuthenticators(const std::string& client_secret,
-                          const std::string& host_secret) {
-    host_ = Spake2Authenticator::CreateForHost(kHostId, kClientId, host_secret,
-                                               host_cert_, key_pair_,
-                                               Authenticator::WAITING_MESSAGE);
-    client_ = Spake2Authenticator::CreateForClient(
-        kClientId, kHostId, client_secret, Authenticator::MESSAGE_READY);
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(Spake2AuthenticatorTest);
-};
-
-TEST_F(Spake2AuthenticatorTest, SuccessfulAuth) {
-  ASSERT_NO_FATAL_FAILURE(
-      InitAuthenticators(kTestSharedSecret, kTestSharedSecret));
-  ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
-
-  ASSERT_EQ(Authenticator::ACCEPTED, host_->state());
-  ASSERT_EQ(Authenticator::ACCEPTED, client_->state());
-
-  client_auth_ = client_->CreateChannelAuthenticator();
-  host_auth_ = host_->CreateChannelAuthenticator();
-  RunChannelAuth(false);
-
-  StreamConnectionTester tester(host_socket_.get(), client_socket_.get(),
-                                kMessageSize, kMessages);
-
-  tester.Start();
-  message_loop_.Run();
-  tester.CheckResults();
-}
-
-// Verify that connection is rejected when secrets don't match.
-TEST_F(Spake2AuthenticatorTest, InvalidSecret) {
-  ASSERT_NO_FATAL_FAILURE(
-      InitAuthenticators(kTestSharedSecretBad, kTestSharedSecret));
-  ASSERT_NO_FATAL_FAILURE(RunAuthExchange());
-
-  ASSERT_EQ(Authenticator::REJECTED, client_->state());
-  ASSERT_EQ(Authenticator::INVALID_CREDENTIALS, client_->rejection_reason());
-
-  // Change |client_| so that we can get the last message.
-  reinterpret_cast<Spake2Authenticator*>(client_.get())->state_ =
-      Authenticator::MESSAGE_READY;
-
-  scoped_ptr<buzz::XmlElement> message(client_->GetNextMessage());
-  ASSERT_TRUE(message.get());
-
-  ASSERT_EQ(Authenticator::WAITING_MESSAGE, client_->state());
-  host_->ProcessMessage(message.get(), base::Bind(&base::DoNothing));
-  // This assumes that Spake2Authenticator::ProcessMessage runs synchronously.
-  ASSERT_EQ(Authenticator::REJECTED, host_->state());
-}
-
-}  // namespace protocol
-}  // namespace remoting
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 9c7c8ca..79057768c 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -236,7 +236,6 @@
         '../crypto/crypto.gyp:crypto',
         '../jingle/jingle.gyp:jingle_glue',
         '../net/net.gyp:net',
-        '../third_party/boringssl/boringssl.gyp:boringssl',
         '../third_party/expat/expat.gyp:expat',
         '../third_party/libjingle/libjingle.gyp:libjingle',
         '../third_party/libyuv/libyuv.gyp:libyuv',
@@ -251,7 +250,7 @@
         '<@(remoting_signaling_sources)',
       ],
       'conditions': [
-        ['enable_webrtc == 1', {
+        ['enable_webrtc==1', {
           'dependencies': [
             '../third_party/libjingle/libjingle.gyp:libjingle_webrtc',
             '../third_party/libjingle/libjingle.gyp:libpeerconnection',
diff --git a/remoting/remoting_srcs.gypi b/remoting/remoting_srcs.gypi
index 59a0559..0788f88 100644
--- a/remoting/remoting_srcs.gypi
+++ b/remoting/remoting_srcs.gypi
@@ -195,8 +195,6 @@
       'protocol/session_manager.h',
       'protocol/socket_util.cc',
       'protocol/socket_util.h',
-      'protocol/spake2_authenticator.cc',
-      'protocol/spake2_authenticator.h',
       'protocol/ssl_hmac_channel_authenticator.cc',
       'protocol/ssl_hmac_channel_authenticator.h',
       'protocol/stream_channel_factory.h',
diff --git a/remoting/remoting_test.gypi b/remoting/remoting_test.gypi
index 7f6858d..5e36aa0 100644
--- a/remoting/remoting_test.gypi
+++ b/remoting/remoting_test.gypi
@@ -337,7 +337,6 @@
         'protocol/ppapi_module_stub.cc',
         'protocol/pseudotcp_adapter_unittest.cc',
         'protocol/session_config_unittest.cc',
-        'protocol/spake2_authenticator_unittest.cc',
         'protocol/ssl_hmac_channel_authenticator_unittest.cc',
         'protocol/third_party_authenticator_unittest.cc',
         'protocol/v2_authenticator_unittest.cc',
diff --git a/sandbox/linux/services/credentials.cc b/sandbox/linux/services/credentials.cc
index 76038af..0e569fa 100644
--- a/sandbox/linux/services/credentials.cc
+++ b/sandbox/linux/services/credentials.cc
@@ -23,7 +23,6 @@
 #include "base/macros.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/process/launch.h"
-#include "base/template_util.h"
 #include "base/third_party/valgrind/valgrind.h"
 #include "build/build_config.h"
 #include "sandbox/linux/services/namespace_utils.h"
diff --git a/sandbox/linux/services/namespace_utils.h b/sandbox/linux/services/namespace_utils.h
index 72310333..ec5d241 100644
--- a/sandbox/linux/services/namespace_utils.h
+++ b/sandbox/linux/services/namespace_utils.h
@@ -7,9 +7,10 @@
 
 #include <sys/types.h>
 
+#include <type_traits>
+
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/template_util.h"
 #include "sandbox/sandbox_export.h"
 
 namespace sandbox {
@@ -17,7 +18,7 @@
 // Utility functions for using Linux namepaces.
 class SANDBOX_EXPORT NamespaceUtils {
  public:
-  static_assert((base::is_same<uid_t, gid_t>::value),
+  static_assert(std::is_same<uid_t, gid_t>::value,
                 "uid_t and gid_t must be the same type");
   // generic_id_t can be used for either uid_t or gid_t.
   typedef uid_t generic_id_t;
diff --git a/storage/browser/quota/quota_callbacks.h b/storage/browser/quota/quota_callbacks.h
index 270e14f..6b968028 100644
--- a/storage/browser/quota/quota_callbacks.h
+++ b/storage/browser/quota/quota_callbacks.h
@@ -10,6 +10,7 @@
 
 #include <map>
 #include <set>
+#include <utility>
 #include <vector>
 
 #include "base/callback.h"
@@ -51,12 +52,11 @@
   }
 
   // Runs the callbacks added to the queue and clears the queue.
-  void Run(
-      typename base::internal::CallbackParamTraits<Args>::ForwardType... args) {
+  void Run(Args... args) {
     std::vector<CallbackType> callbacks;
     callbacks.swap(callbacks_);
     for (const auto& callback : callbacks)
-      callback.Run(base::internal::CallbackForward(args)...);
+      callback.Run(args...);
   }
 
   void Swap(CallbackQueue<CallbackType, Args...>* other) {
@@ -97,15 +97,14 @@
 
   // Runs the callbacks added for the given |key| and clears the key
   // from the map.
-  void Run(
-      const Key& key,
-      typename base::internal::CallbackParamTraits<Args>::ForwardType... args) {
+  template <typename... RunArgs>
+  void Run(const Key& key, RunArgs&&... args) {
     if (!this->HasCallbacks(key))
       return;
     CallbackQueueType queue;
     queue.Swap(&callback_map_[key]);
     callback_map_.erase(key);
-    queue.Run(base::internal::CallbackForward(args)...);
+    queue.Run(std::forward<RunArgs>(args)...);
   }
 
  private:
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 2cfe693..b79122a 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -267,6 +267,9 @@
         "test": "sync_unit_tests"
       },
       {
+        "test": "ui_arc_unittests"
+      },
+      {
         "swarming": {
           "can_use_on_swarming_builders": true
         },
@@ -563,6 +566,9 @@
         "test": "sync_unit_tests"
       },
       {
+        "test": "ui_arc_unittests"
+      },
+      {
         "swarming": {
           "can_use_on_swarming_builders": true
         },
@@ -858,6 +864,9 @@
         "test": "sync_unit_tests"
       },
       {
+        "test": "ui_arc_unittests"
+      },
+      {
         "swarming": {
           "can_use_on_swarming_builders": true
         },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 5057b1d..7460b60 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -492,6 +492,9 @@
         "test": "sync_unit_tests"
       },
       {
+        "test": "ui_arc_unittests"
+      },
+      {
         "swarming": {
           "can_use_on_swarming_builders": true
         },
diff --git a/testing/buildbot/chromium_trybot.json b/testing/buildbot/chromium_trybot.json
index 24a7696..558cec1 100644
--- a/testing/buildbot/chromium_trybot.json
+++ b/testing/buildbot/chromium_trybot.json
@@ -299,6 +299,17 @@
       ],
       "test": "ui_chromeos_unittests"
     },
+    {
+      "chromium_configs": [
+        "chromium_chromeos",
+        "chromium_chromeos_clang",
+        "chromium_chromeos_ozone"
+      ],
+      "platforms": [
+        "linux"
+      ],
+      "test": "ui_arc_unittests"
+    },
     "url_unittests",
     "skia_unittests",
     {
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 00e2fdd..85bb482 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -518,6 +518,11 @@
     "label": "//ui/chromeos:ui_chromeos_unittests",
     "type": "unknown",
   },
+  "ui_arc_unittests": {
+    "label": "//ui/arc:ui_arc_unittests",
+    "type": "raw",
+    "args": [],
+  },
   "ui_touch_selection_unittests": {
     "label": "//ui/touch_selection:ui_touch_selection_unittests",
     "type": "windowed_test_launcher",
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index 4593812..3fcee72 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -21,7 +21,6 @@
 crbug.com/24182 editing/selection/move-by-word-visually-multi-space.html [ Slow ]
 crbug.com/24182 editing/selection/move-by-word-visually-crash-test-5.html [ Slow ]
 crbug.com/24182 fast/dom/SelectorAPI/resig-SelectorsAPI-test.xhtml [ Slow ]
-crbug.com/24182 fast/dynamic/window-resize-scrollbars-test.html [ Slow ]
 crbug.com/24182 fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer.html [ Slow ]
 crbug.com/24182 fast/frames/cached-frame-counter.html [ Slow ]
 crbug.com/24182 fast/frames/frame-limit.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 46365a0..62c2cb3 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -161,7 +161,6 @@
 crbug.com/521094 [ Mac ] http/tests/navigation/beacon-cross-origin.https.html [ Crash Failure Pass ]
 crbug.com/521096 imported/web-platform-tests/webstorage/event_case_sensitive.html [ Failure Pass ]
 crbug.com/521107 [ Debug ] fast/html/imports/import-custom-element-abort.html [ Crash Pass ]
-crbug.com/520164 [ Linux ] accessibility/is-richly-editable.html [ Failure Pass ]
 crbug.com/520166 compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html [ Failure Pass ]
 crbug.com/520169 [ Win ] fast/dom/Geolocation/timestamp.html [ Failure Pass ]
 crbug.com/520170 [ Win ] fast/dom/timer-throttling-hidden-page.html [ Failure Pass ]
@@ -461,6 +460,8 @@
 crbug.com/589267 virtual/spv2/fast/overflow/table-overflow-float.html [ Failure ]
 crbug.com/589267 virtual/spv2/fast/overflow/unreachable-overflow-rtl-bug.html [ Failure ]
 crbug.com/589279 virtual/spv2/fast/overflow/006.html [ Failure ]
+crbug.com/589279 virtual/spv2/fast/overflow/hidden-viewport-x.html [ Failure ]
+crbug.com/589279 virtual/spv2/fast/overflow/hidden-viewport-y.html [ Failure ]
 crbug.com/589279 virtual/spv2/fast/overflow/position-fixed-transform-clipping.html [ Failure ]
 
 crbug.com/537409 virtual/spv2/svg/as-image/svg-image-with-data-uri.html [ Pass ]
@@ -779,7 +780,7 @@
 crbug.com/492664 [ Mac ] imported/csswg-test/css-writing-modes-3/text-baseline-vlr-007.xht [ Failure ]
 
 crbug.com/498845 [ Win ] fast/multicol/vertical-rl/float-content-break.html [ Failure ]
-
+crbug.com/593184 editing/inserting/4960120-1.html [ NeedsRebaseline ]
 crbug.com/443615 [ Linux Win ] imported/csswg-test/css-shapes-1/shape-outside/supported-shapes/circle/shape-outside-circle-027.html [ Failure ]
 
 crbug.com/443379 imported/web-platform-tests/gamepad/idlharness.html [ Failure Timeout ]
@@ -997,6 +998,9 @@
 crbug.com/519124 fast/text/zero-font-size.html [ NeedsRebaseline ]
 
 crbug.com/467127 imported/csswg-test/css-flexbox-1/flex-grow-006.html [ Failure ]
+crbug.com/467127 imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-003.html [ Failure ]
+crbug.com/467127 imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-002.html [ Failure ]
+crbug.com/467127 imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-003.html [ Failure ]
 crbug.com/467127 imported/csswg-test/css-flexbox-1/flexbox_justifycontent-center-overflow.html [ Failure ]
 crbug.com/467127 imported/csswg-test/css-flexbox-1/getcomputedstyle/flexbox_computedstyle_align-items-invalid.html [ Failure ]
 crbug.com/467127 imported/csswg-test/css-flexbox-1/getcomputedstyle/flexbox_computedstyle_align-self-invalid.html [ Failure ]
@@ -1082,6 +1086,28 @@
 crbug.com/321237 [ Win ] fast/multicol/span/pseudo-before-after-in-content.html [ Failure ]
 crbug.com/321237 [ Win ] fast/selectors/004.html [ Failure ]
 
+crbug.com/579842 [ Win ] fast/css/line-height-determined-by-primary-font.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/forms/datetimelocal/datetimelocal-appearance-l10n.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/forms/month/month-appearance-l10n.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/forms/placeholder-position.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/text/international/lang-glyph-cache-separation.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/text/international/plane2.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/text/justify-ideograph-complex.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/text/justify-ideograph-simple.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/writing-mode/fallback-orientation.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/writing-mode/vertical-align-table-baseline.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/writing-mode/vertical-baseline-alignment.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] fast/writing-mode/vertical-font-fallback.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] inspector-protocol/layout-fonts/cjk-ideograph-fallback-by-lang.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.html [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] svg/W3C-SVG-1.1/text-align-08-b.svg [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] svg/W3C-SVG-1.1/text-fonts-01-t.svg [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] svg/W3C-SVG-1.1/text-intro-01-t.svg [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] svg/W3C-SVG-1.1/text-intro-03-b.svg [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] svg/W3C-SVG-1.1/text-intro-04-t.svg [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] svg/batik/text/verticalText.svg [ NeedsRebaseline ]
+crbug.com/579842 [ Win ] svg/text/text-selection-fonts-01-t.svg [ NeedsRebaseline ]
+
 crbug.com/501659 fast/xsl/xslt-missing-namespace-in-xslt.xml [ Failure ]
 
 crbug.com/501659 http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ]
@@ -1119,6 +1145,9 @@
 
 crbug.com/464736 http/tests/xmlhttprequest/ontimeout-event-override-after-failure.html [ Pass Failure ]
 
+crbug.com/591901 [ Win ] fast/images/color-profile-background-clip-text.html [ Failure ]
+crbug.com/591901 [ Win ] fast/images/color-profile-svg-fill-text.html [ Failure ]
+
 crbug.com/521730 [ Win10 ] fast/forms/month-multiple-fields/month-multiple-fields-preserve-value-after-history-back.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/forms/month-multiple-fields/month-multiple-fields-value-set-empty.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/forms/suggested-value.html [ Failure ]
@@ -1152,7 +1181,6 @@
 crbug.com/521730 [ Win10 ] fast/text/international/bidi-linebreak-003.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text/international/bidi-word-spacing-rtl.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text/international/inline-block-with-mixed-direction-words.html [ Failure ]
-crbug.com/521730 [ Win10 ] fast/text/international/plane2.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text/letter-spacing-negative-opacity.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text/line-breaks-after-white-space.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text/line-breaks.html [ Failure ]
@@ -1160,7 +1188,6 @@
 crbug.com/521730 [ Win10 ] fast/text/stroking-decorations.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text/trailing-white-space-2.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text/whitespace/nbsp-mode-and-linewraps.html [ Failure ]
-crbug.com/521730 [ Win10 ] fast/writing-mode/vertical-font-fallback.html [ Failure ]
 crbug.com/521730 [ Win10 ] svg/css/text-gradient-shadow.svg [ Failure ]
 crbug.com/521730 [ Win10 ] compositing/squashing/squashing-print.html [ Failure ]
 crbug.com/521730 [ Win10 ] printing/quirks-percentage-height-body.html [ Failure ]
@@ -1183,7 +1210,6 @@
 crbug.com/521730 [ Win10 ] fast/text/international/hindi-whitespace.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/writing-mode/border-vertical-lr.html [ Failure ]
 crbug.com/521730 [ Win10 ] media/track/track-cue-rendering-vertical.html [ Failure ]
-crbug.com/521730 [ Win10 ] fast/css/line-height-determined-by-primary-font.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/forms/month/month-appearance-pseudo-elements.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text-autosizing/display-type-change.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text-autosizing/tables/css-table-single-cell-lots-of-text.html [ Failure ]
@@ -1210,11 +1236,8 @@
 crbug.com/521730 [ Win10 ] fast/text/sub-pixel/text-scaling-pixel.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text/trailing-white-space.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/text/wide-zero-width-space.html [ Failure ]
-crbug.com/521730 [ Win10 ] fast/writing-mode/fallback-orientation.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/writing-mode/japanese-lr-text.html [ Failure ]
 crbug.com/521730 [ Win10 ] fast/writing-mode/japanese-rl-text.html [ Failure ]
-crbug.com/521730 [ Win10 ] fast/writing-mode/vertical-align-table-baseline.html [ Failure ]
-crbug.com/521730 [ Win10 ] fast/writing-mode/vertical-baseline-alignment.html [ Failure ]
 crbug.com/521730 [ Win10 ] fonts/fantasy.html [ Failure ]
 crbug.com/521730 [ Win10 ] ietestcenter/css3/text/textshadow-002.htm [ Failure ]
 crbug.com/521730 [ Win10 ] ietestcenter/css3/text/textshadow-010.htm [ Failure ]
@@ -1342,6 +1365,7 @@
 
 crbug.com/587593 [ Android ] fast/js/pic/cached-single-entry-transition.html [ Pass Failure ]
 
+crbug.com/587779 [ Linux Mac10.10 Mac10.11 Retina ] fast/dynamic/window-resize-scrollbars-test.html [ Timeout Failure Pass ]
 crbug.com/588061 [ Debug ] inspector/sources/debugger-breakpoints/debugger-reload-breakpoints-with-source-maps.html [ Pass Failure ]
 
 crbug.com/588103 fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer.html [ Pass Failure ]
@@ -1390,8 +1414,14 @@
 crbug.com/591821 virtual/trustedeventsdefaultaction/fast/events/scale-and-scroll-iframe-body.html [ Failure Pass ]
 crbug.com/591821 virtual/trustedeventsdefaultaction/fast/events/updateLayoutForHitTest.html [ Failure Pass ]
 
+crbug.com/593568 [ Win Debug ] virtual/threaded/fast/scroll-behavior/smooth-scroll/horizontal-smooth-scroll-in-rtl.html [ Failure ] 
+
 crbug.com/591825 [ Mac10.11 Debug ] fast/text/selection-multiple-runs.html [ Failure ]
 
+crbug.com/593567 [ Linux Win Debug ] virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance.html [ Failure ] 
+crbug.com/593567 [ Linux Win Debug ] virtual/scalefactor150/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure ]
+crbug.com/593567 [ Linux Win Debug ] virtual/scalefactor150/fast/hidpi/static/popup-menu-appearance.html [ Failure ]
+
 crbug.com/591832 [ Mac10.10 Mac10.11 Retina ] compositing/layer-creation/compositing-reason-removed.html [ Failure ]
 crbug.com/591832 [ Mac10.11 Retina ] compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html [ Failure ]
 crbug.com/591832 [ Mac10.10 Mac10.11 Retina ] compositing/overflow/fixed-scroll-in-empty-root-layer.html [ Failure ]
@@ -1416,3 +1446,5 @@
 
 crbug.com/592409 inspector-protocol/debugger/stepping-with-blackboxed-ranges.html [ NeedsManualRebaseline ]
 
+crbug.com/559258 [ Mac10.10 ] scrollbars/listbox-scrollbar-combinations.html [ Failure ]
+crbug.com/559258 [ Mac10.10 ] virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations
index b58a1e88..121e5937 100644
--- a/third_party/WebKit/LayoutTests/W3CImportExpectations
+++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -15,6 +15,7 @@
 imported/csswg-test/css-backgrounds-3 [ Skip ]
 imported/csswg-test/css-box-3 [ Skip ]
 imported/csswg-test/css-break-3 [ Skip ]
+imported/csswg-test/css-cascade-3 [ Skip ]
 imported/csswg-test/css-color-3 [ Skip ]
 imported/csswg-test/css-color-4 [ Skip ]
 imported/csswg-test/css-conditional-3 [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/accessibility/deleting-iframe-destroys-axcache-expected.txt b/third_party/WebKit/LayoutTests/accessibility/deleting-iframe-destroys-axcache-expected.txt
deleted file mode 100644
index 9f05038..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/deleting-iframe-destroys-axcache-expected.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-Before
-
-After
-
-End of test
-
-This tests that deleting an iframe doesn't cause the accessibility cache to be destroyed and recreated.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-Before:
-AXRole: AXWebArea
-    AXRole: AXParagraph
-        AXRole: AXStaticText "Before"
-            AXRole: AXInlineTextBox "Before"
-    AXRole: AXGroup
-        AXRole: AXUnknown
-            AXRole: AXWebArea
-                AXRole: AXGroup
-                    AXRole: AXButton "Click me"
-    AXRole: AXParagraph
-        AXRole: AXStaticText "After"
-            AXRole: AXInlineTextBox "After"
-    AXRole: AXParagraph
-        AXRole: AXStaticText "End of test"
-
-After:
-AXRole: AXWebArea
-    AXRole: AXParagraph
-        AXRole: AXStaticText "Before"
-            AXRole: AXInlineTextBox "Before"
-    AXRole: AXParagraph
-        AXRole: AXStaticText "After"
-            AXRole: AXInlineTextBox "After"
-    AXRole: AXParagraph
-        AXRole: AXStaticText "End of test"
-
-PASS frameBodyRole == frameBody.role is false
-PASS frameGroupRole == frameGroup.role is false
-PASS frameButtonRole == frameButton.role is false
-PASS before.isEqual(newBefore) is true
-PASS after.isEqual(newAfter) is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/accessibility/deleting-iframe-destroys-axcache.html b/third_party/WebKit/LayoutTests/accessibility/deleting-iframe-destroys-axcache.html
deleted file mode 100644
index dc38ba2..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/deleting-iframe-destroys-axcache.html
+++ /dev/null
@@ -1,77 +0,0 @@
-<html>
-<script src="../resources/js-test.js"></script>
-<script src="../resources/accessibility-helper.js"></script>
-<body>
-
-<p id="before">Before</p>
-
-<iframe id="iframe" src="data:text/html,<body><button>Click me</button></body>"></iframe>
-
-<p id="after">After</p>
-
-<p>End of test</p>
-
-<p id="description"></p>
-<div id="console"></div>
-<script>
-    if (window.testRunner)
-        testRunner.waitUntilDone();
-
-    function runTest()
-    {
-        description("This tests that deleting an iframe doesn't cause the accessibility cache to be destroyed and recreated.");
-
-        if (window.accessibilityController) {
-            window.before = accessibilityController.accessibleElementById('before');
-            window.iframe = accessibilityController.accessibleElementById('iframe');
-            window.after = accessibilityController.accessibleElementById('after');
-            window.root = before.parentElement();
-
-            window.frameBody = iframe.childAtIndex(0);
-            window.frameBodyRole = frameBody.role;
-            window.frameGroup = frameBody.childAtIndex(0);
-            window.frameGroupRole = frameGroup.role;
-            window.frameButton = frameGroup.childAtIndex(0);
-            window.frameButtonRole = frameButton.role;
-
-            document.getElementById("console").innerText += "\nBefore:\n";
-            buildAccessibilityTree(root, 0, 1);
-
-            // Remove the iframe.
-            document.body.removeChild(document.getElementById("iframe"));
-
-            // Force layout now so that the childAtIndex calls below
-            // reflect the new render tree.
-            document.body.offsetTop;
-
-            window.newBefore = accessibilityController.accessibleElementById('before');
-            window.newAfter = accessibilityController.accessibleElementById('after');
-            window.newRoot = newBefore.parentElement();
-
-            document.getElementById("console").innerText += "\nAfter:\n";
-            buildAccessibilityTree(newRoot, 0, 1);
-            document.getElementById("console").innerText += "\n";
-
-            // Make sure that the accessibility objects from the iframe's nodes
-            // are now invalid by checking that their role is changed - this
-            // is because they've been deleted.
-            shouldBeFalse("frameBodyRole == frameBody.role");
-            shouldBeFalse("frameGroupRole == frameGroup.role");
-            shouldBeFalse("frameButtonRole == frameButton.role");
-
-            // Make sure that the other nodes are unchanged.
-            shouldBeTrue("before.isEqual(newBefore)");
-            shouldBeTrue("after.isEqual(newAfter)");
-        }
-
-        debug('<br /><span class="pass">TEST COMPLETE</span>');
-        if (window.testRunner)
-            testRunner.notifyDone();
-    }
-
-    window.addEventListener('load', function() {
-        setTimeout(runTest, 10);
-    }, false);
-</script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt
index 8584a35..87a2323 100644
--- a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt
+++ b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt
@@ -33,7 +33,6 @@
 Visit us at:www.chromium.org
 January This is an open dialog window
 
- 
 Caption
 Cell1	Cell2
 
@@ -168,11 +167,6 @@
         AXRole: AXDialog
             AXRole: AXStaticText "This is an open dialog window"
                 AXRole: AXInlineTextBox "This is an open dialog window"
-    AXRole: AXGroup
-        AXRole: AXUnknown
-            AXRole: AXWebArea
-        AXRole: AXUnknown
-            AXRole: AXWebArea
     AXRole: AXTable "Caption"
         AXRole: AXCaption
             AXRole: AXStaticText "Caption"
diff --git a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal.html b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal.html
index f525dbd..55e57fdb 100644
--- a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal.html
+++ b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal.html
@@ -57,15 +57,13 @@
   <p>Section</p>
   <footer>
     <p>Footer in section</p>
-  </footer>  
+  </footer>
 </section>
 <address>
-Written by Julie<br> 
+Written by Julie<br>
 Visit us at:www.chromium.org<br>
 </address>
 <p>January <dialog open>This is an open dialog window</dialog></p>
-<iframe src="about:blank"></iframe>
-<iframe src="about:blank" role="presentation"></iframe>
 <table>
   <caption>Caption</caption>
   <tr>
diff --git a/third_party/WebKit/LayoutTests/accessibility/event-on-deleted-iframe-causes-crash-expected.txt b/third_party/WebKit/LayoutTests/accessibility/event-on-deleted-iframe-causes-crash-expected.txt
deleted file mode 100644
index bbaa25fa..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/event-on-deleted-iframe-causes-crash-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Lorem
-more Lorem!
-ipsum
-
diff --git a/third_party/WebKit/LayoutTests/accessibility/event-on-deleted-iframe-causes-crash.html b/third_party/WebKit/LayoutTests/accessibility/event-on-deleted-iframe-causes-crash.html
deleted file mode 100644
index e70a968e..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/event-on-deleted-iframe-causes-crash.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<div contenteditable="true">
-   <span id="item1">Lorem
-   <br/>
-   more Lorem!
-   <blockquote>
-      ipsum
-   <span id="item2">
-</div>
-
-<script>
-    if (window.testRunner)
-        testRunner.dumpAsText();
-
-    var s = window.getSelection();
-    var p1 = document.getElementById("item1");
-    var p2 = document.getElementById("item2");
-    s.setBaseAndExtent(p1, 0, p2);
-    document.execCommand("Indent");
-
-    // This code doesn't do anything initially, but the code below creates an iframe
-    // with the same url as this one, and that time it will delete itself.
-    var frame = window.parent.document.querySelector('iframe');
-    if (frame)
-        frame.remove();
-</script>
-<script>
-    // This creates an iframe with the same url as this one, which triggers
-    // the code above that deletes this iframe, and then triggers a possible crash
-    // when the execCommand fires accessibility notifications that trigger creation
-    // of the AXScrollArea corresponding to the frame that's in the process of
-    // being deleted.
-    var iframe = document.createElement('iframe');
-    iframe.src = window.location;
-    document.body.appendChild(iframe);
-</script>
diff --git a/third_party/WebKit/LayoutTests/accessibility/is-richly-editable-expected.txt b/third_party/WebKit/LayoutTests/accessibility/is-richly-editable-expected.txt
index 58f16a06..a58be52 100644
--- a/third_party/WebKit/LayoutTests/accessibility/is-richly-editable-expected.txt
+++ b/third_party/WebKit/LayoutTests/accessibility/is-richly-editable-expected.txt
@@ -3,30 +3,27 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+PASS axElement.isRichlyEditable is true
+PASS axElement.isRichlyEditable is true
+PASS axElement.isRichlyEditable is true
+PASS axElement.isRichlyEditable is true
+PASS axElement.isRichlyEditable is true
+PASS axElement.isRichlyEditable is true
+PASS axElement.isRichlyEditable is false
+PASS axElement.isRichlyEditable is false
+PASS axElement.isRichlyEditable is false
+PASS axElement.isRichlyEditable is false
+PASS axElement.isRichlyEditable is false
+PASS axElement.isRichlyEditable is false
+PASS axElement.isRichlyEditable is false
 PASS successfullyParsed is true
 
 TEST COMPLETE
-PASS axElement.isRichlyEditable is true
-PASS axElement.isRichlyEditable is true
-PASS axElement.isRichlyEditable is true
-PASS axElement.isRichlyEditable is true
-PASS axElement.isRichlyEditable is true
-PASS axElement.isRichlyEditable is true
-PASS axElement.isRichlyEditable is true
-PASS axElement.isRichlyEditable is true
-PASS axElement.isRichlyEditable is false
-PASS axElement.isRichlyEditable is false
-PASS axElement.isRichlyEditable is false
-PASS axElement.isRichlyEditable is false
-PASS axElement.isRichlyEditable is false
-PASS axElement.isRichlyEditable is false
-PASS axElement.isRichlyEditable is false
-PASS axElement.isRichlyEditable is false
 Some text.
 
 Some text.
 
-    
+   
 Some text.
 
 Some text.
diff --git a/third_party/WebKit/LayoutTests/accessibility/is-richly-editable.html b/third_party/WebKit/LayoutTests/accessibility/is-richly-editable.html
index d97dac2..089c3018 100644
--- a/third_party/WebKit/LayoutTests/accessibility/is-richly-editable.html
+++ b/third_party/WebKit/LayoutTests/accessibility/is-richly-editable.html
@@ -17,9 +17,6 @@
     style="border: 1px solid #000000;">
     <div id="richly_editable6" contentEditable="true">Some text.</div>
 </canvas>
-<iframe id="richly_editable7"
-    src="data:text/html,<html><body><p>Some text.</p></body></html>">
-</iframe>
 
 <!-- Non-richly editable elements. -->
 <input id="non_richly_editable1" type="text" value="Some text.">
@@ -37,38 +34,22 @@
 <script>
     description("This tests that only elements that allow the user to edit rich text in them are recognized as being richly editable.");
 
-    var iframeId = "richly_editable7";
-    var iframe = document.getElementById(iframeId);
-    window.axElement = undefined; // Needs to be globally declared for test expectations to work.
-    iframe.onload = function()
-    {
-        var iframeDocument = iframe.contentDocument;
-        iframeDocument.designMode = "on";
+    if (window.accessibilityController) {
 
-        if (window.accessibilityController) {
-
-            for (var i = 1; i <= 7; ++i) {
-                var elementId = "richly_editable" + i;
-                var element = document.getElementById(elementId);
-                element.focus();
-                window.axElement = accessibilityController.focusedElement;
-                shouldBeTrue("axElement.isRichlyEditable");
-            }
-
-            // Both the iframe itself (tested above) and its body should be richly editable.
-            iframeDocument.body.focus();
-            window.axElement = accessibilityController.focusedElement;
+        for (var i = 1; i <= 6; ++i) {
+            var elementId = "richly_editable" + i;
+            var element = document.getElementById(elementId);
+            element.focus();
+            var axElement = accessibilityController.focusedElement;
             shouldBeTrue("axElement.isRichlyEditable");
-
-
-            for (var i = 1; i <= 8; ++i) {
-                var elementId = "non_richly_editable" + i;
-                var element = document.getElementById(elementId);
-                element.focus();
-                window.axElement = accessibilityController.focusedElement;
-                shouldBeFalse("axElement.isRichlyEditable");
-            }
-
         }
-    };
+
+        for (var i = 1; i <= 7; ++i) {
+            var elementId = "non_richly_editable" + i;
+            var element = document.getElementById(elementId);
+            element.focus();
+            var axElement = accessibilityController.focusedElement;
+            shouldBeFalse("axElement.isRichlyEditable");
+        }
+    }
 </script>
diff --git a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-sends-notification-expected.txt b/third_party/WebKit/LayoutTests/accessibility/loading-iframe-sends-notification-expected.txt
deleted file mode 100644
index afec33fd..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-sends-notification-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Before
-
-
-After
-
-End of test
-
-This tests that when an iframe finishes loading, it sends a notification.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS accessibilityController.accessibleElementById('innerbutton') is undefined.
-PASS accessibilityController.accessibleElementById('innerbutton') is defined.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-sends-notification.html b/third_party/WebKit/LayoutTests/accessibility/loading-iframe-sends-notification.html
deleted file mode 100644
index 203b03c..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-sends-notification.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<html>
-<head>
-<script src="../resources/js-test.js"></script>
-</head>
-<body>
-
-<p>Before</p>
-
-<iframe id="iframe" title="InnerFrame"></iframe>
-
-<p>After</p>
-
-<p>End of test</p>
-
-<p id="description"></p>
-<div id="console"></div>
-
-<script>
-    description("This tests that when an iframe finishes loading, it sends a notification.");
-
-    if (window.testRunner)
-        testRunner.waitUntilDone();
-    else
-        debug("This test requires window.accessibilityController and must be run in content_shell with --run-layout-test.")
-
-    window.jsTestIsAsync = true;
-
-    function runTest()
-    {
-        if (window.accessibilityController) {
-            // Initially, the iframe should not be loaded, so we shouldn't be able to find this button.
-            shouldBeUndefined("accessibilityController.accessibleElementById('innerbutton')");
-
-            window.accessibilityController.addNotificationListener(function (target, notification) {
-                if (!target.parentElement())
-                    return;
-
-                // Ignore this notification if it's not within the subtree of the iframe.
-                var frameTarget = target.parentElement();
-                if (frameTarget.name.indexOf("InnerFrame") == -1)
-                    return;
-
-                // Even still we'll get LayoutComplete notifications sooner than we want.
-                if (!accessibilityController.accessibleElementById('innerbutton'))
-                    return;
-
-                // Check that the button within the iframe is now reachable from the root.
-                shouldBeDefined("accessibilityController.accessibleElementById('innerbutton')");
-                if (window.accessibilityController)
-                    accessibilityController.removeNotificationListener();
-
-                finishJSTest();
-            });
-        }
-
-        // Load content into the iframe. This will trigger the event
-        // handler above, which will check that the accessibility tree
-        // was updated with new content.
-        document.getElementById("iframe").src = "data:text/html,<body><button id='innerbutton'>InnerButton</button></body>";
-    }
-    window.addEventListener('load', runTest);
-</script>
-
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree-expected.txt b/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree-expected.txt
deleted file mode 100644
index c9170f3..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Before
-
-
-After
-
-End of test
-
-This tests that if an iframe loads new content after its accessibility object has already been accessed, the iframe accessibility object's descendants are the new scroll area and web area, not the old deleted ones.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-PASS iframe.isEqual(newIframe) is true
-PASS subwebarea.isEqual(newSubwebarea) is false
-PASS newSubwebarea.childrenCount > 0 is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree.html b/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree.html
deleted file mode 100644
index dbb726c0..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/loading-iframe-updates-axtree.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<html>
-<head>
-<script src="../resources/js-test.js"></script>
-
-  <script>
-    if (window.testRunner)
-        testRunner.waitUntilDone();
-
-    function runTest()
-    {
-        description("This tests that if an iframe loads new content after its accessibility object has already been accessed, the iframe accessibility object's descendants are the new scroll area and web area, not the old deleted ones.");
-
-        if (window.accessibilityController) {
-            window.iframe = accessibilityController.accessibleElementById('iframe');
-            window.subwebarea = iframe.childAtIndex(0);
-        }
-
-        window.iframeElement = document.getElementById("iframe");
-        iframeElement.addEventListener("load", function() {
-            if (window.accessibilityController) {
-                window.newIframe = accessibilityController.accessibleElementById('iframe');
-                window.newSubwebarea = newIframe.childAtIndex(0);
-
-                shouldBeTrue("iframe.isEqual(newIframe)");
-                shouldBeFalse("subwebarea.isEqual(newSubwebarea)");
-                shouldBeTrue("newSubwebarea.childrenCount > 0");
-            }
-
-            debug('<br /><span class="pass">TEST COMPLETE</span>');
-            if (window.testRunner)
-                testRunner.notifyDone();
-        }, false);
-
-        // Load content into the iframe. This will trigger the event
-        // handler above, which will check that the accessibility tree
-        // was updated with new content.
-        window.iframeElement.src = "data:text/html,<body><button>Click me</button></body>";
-
-    }
-
-    window.addEventListener('load', function() {
-        runTest();
-    }, false);
-
-  </script>
-</head>
-<body>
-
-<p>Before</p>
-
-<iframe id="iframe" role="group"></iframe>
-
-<p>After</p>
-
-<p>End of test</p>
-
-<p id="description"></p>
-<div id="console"></div>
-
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe-expected.txt b/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe-expected.txt
deleted file mode 100644
index ab7072d6..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Tests that scrolling to move an element to a specific point successfully scrolls an iframe.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-5000-pixel box
-
-5000-pixel box
-PASS window.pageYOffset is 0
-PASS frameWindow.pageYOffset is 0
-PASS target.getBoundingClientRect().top is 0
-PASS target.getBoundingClientRect().top is 300
-PASS target.getBoundingClientRect().top is 3000
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe-nested-expected.txt b/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe-nested-expected.txt
deleted file mode 100644
index 11435a3da..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe-nested-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Tests that scrolling to move an element to a specific point successfully scrolls both an iframe and a div with overflow.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-5000-pixel box
-
-5000-pixel box
-PASS window.pageYOffset is 0
-PASS frameWindow.pageYOffset is 0
-PASS container.scrollTop is 0
-PASS target.getBoundingClientRect().top is 0
-PASS target.getBoundingClientRect().top is 300
-PASS target.getBoundingClientRect().top is 3000
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe-nested.html b/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe-nested.html
deleted file mode 100644
index 26c2a7a0..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe-nested.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<html>
-<head>
-<script src="../resources/js-test.js"></script>
-</head>
-<body>
-
-<p id="description"></p>
-
-<div style="border: 1px solid #000; height: 5000px;">5000-pixel box</div>
-
-<!-- The contents of this iframe, more nicely formatted:
- <body>
-   <style>
-     button {
-       border: 0;
-     }
-   </style>
-   <div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div>
-   <div id='container' style='height: 100px; overflow: scroll'>
-     <div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div>
-     <button id='target'>Target</button>
-     <div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div>
-   </div>
-   <div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div>
-  </body>
- -->
-<iframe id="frame" src="data:text/html,<body><style>button { border: 0; }</style><div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div><div id='container' style='height: 100px; overflow: scroll'><div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div><button id='target'>Target</button><div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div></div><div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div></body>"></iframe>
-
-<div style="border: 1px solid #000; height: 5000px;">5000-pixel box</div>
-
-<div id="console"></div>
-
-<script>
-description("Tests that scrolling to move an element to a specific point successfully scrolls both an iframe and a div with overflow.");
-
-if (window.testRunner)
-        testRunner.waitUntilDone();
-
-window.jsTestIsAsync = true;
-
-function runTest() {
-    window.frame = document.getElementById("frame");
-    window.frameWindow = frame.contentWindow;
-    window.frameDoc = frameWindow.document;
-    window.container = frameDoc.getElementById("container");
-    window.target = frameDoc.getElementById("target");
-
-    if (window.accessibilityController) {
-        target.focus();
-        var targetAccessibleObject = accessibilityController.focusedElement;
-    }
-
-    // Reset the initial scroll position (since calling focus() can scroll the page too).
-    window.scrollTo(0, 0);
-    frameWindow.scrollTo(0, 0);
-    container.scrollTop = 0;
-    shouldBe("window.pageYOffset", "0");
-    shouldBe("frameWindow.pageYOffset", "0");
-    shouldBe("container.scrollTop", "0");
-
-    // Scroll to various locations and check.
-    if (window.accessibilityController)
-        targetAccessibleObject.scrollToGlobalPoint(0, 0);
-    shouldBe("target.getBoundingClientRect().top", "0");
-    if (window.accessibilityController)
-        targetAccessibleObject.scrollToGlobalPoint(0, 300);
-    shouldBe("target.getBoundingClientRect().top", "300");
-    if (window.accessibilityController)
-        targetAccessibleObject.scrollToGlobalPoint(0, 3000);
-    shouldBe("target.getBoundingClientRect().top", "3000");
-
-    finishJSTest();
-}
-
-window.addEventListener('load', function() {
-    setTimeout(runTest, 10);
-}, false);
-
-</script>
-
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe.html b/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe.html
deleted file mode 100644
index 0e258931..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/scroll-to-global-point-iframe.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<html>
-<head>
-<script src="../resources/js-test.js"></script>
-</head>
-<body>
-
-<p id="description"></p>
-
-<div style="border: 1px solid #000; height: 5000px;">5000-pixel box</div>
-
-<iframe id="frame" src="data:text/html,<body><style>button { border: 0; }</style><div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div><button id='target'>Target</button><div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div></body>"></iframe>
-
-<div style="border: 1px solid #000; height: 5000px;">5000-pixel box</div>
-
-<div id="console"></div>
-
-<script>
-description("Tests that scrolling to move an element to a specific point successfully scrolls an iframe.");
-
-if (window.testRunner)
-        testRunner.waitUntilDone();
-
-window.jsTestIsAsync = true;
-
-function runTest() {
-    window.frame = document.getElementById("frame");
-    window.frameWindow = frame.contentWindow;
-    window.frameDoc = frameWindow.document;
-    window.target = frameDoc.getElementById("target");
-
-    if (window.accessibilityController) {
-        target.focus();
-        var targetAccessibleObject = accessibilityController.focusedElement;
-    }
-
-    // Reset the initial scroll position (since calling focus() can scroll the page too).
-    window.scrollTo(0, 0);
-    frameWindow.scrollTo(0, 0);
-    shouldBe("window.pageYOffset", "0");
-    shouldBe("frameWindow.pageYOffset", "0");
-
-    // Scroll to various locations and check.
-    if (window.accessibilityController)
-        targetAccessibleObject.scrollToGlobalPoint(0, 0);
-    shouldBe("target.getBoundingClientRect().top", "0");
-    if (window.accessibilityController)
-        targetAccessibleObject.scrollToGlobalPoint(0, 300);
-    shouldBe("target.getBoundingClientRect().top", "300");
-    if (window.accessibilityController)
-        targetAccessibleObject.scrollToGlobalPoint(0, 3000);
-    shouldBe("target.getBoundingClientRect().top", "3000");
-
-    finishJSTest();
-}
-
-window.addEventListener('load', function() {
-    setTimeout(runTest, 10);
-}, false);
-
-</script>
-
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/accessibility/scroll-to-make-visible-iframe-expected.txt b/third_party/WebKit/LayoutTests/accessibility/scroll-to-make-visible-iframe-expected.txt
deleted file mode 100644
index ca325d5..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/scroll-to-make-visible-iframe-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Tests that scrolling to make an element visible successfully scrolls an iframe.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-
-PASS frameWindow.pageYOffset is 0
-PASS frameWindow.pageYOffset >= minYOffset is true
-PASS frameWindow.pageYOffset <= maxYOffset is true
-PASS frameWindow.pageYOffset >= minYOffset is true
-PASS frameWindow.pageYOffset <= maxYOffset is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/accessibility/scroll-to-make-visible-iframe.html b/third_party/WebKit/LayoutTests/accessibility/scroll-to-make-visible-iframe.html
deleted file mode 100644
index 0f168dd..0000000
--- a/third_party/WebKit/LayoutTests/accessibility/scroll-to-make-visible-iframe.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<html>
-<head>
-<script src="../resources/js-test.js"></script>
-</head>
-<body>
-
-<p id="description"></p>
-
-<iframe id="frame" src="data:text/html,<body><button id='upper_target'>Upper Target</button><div style='border: 1px solid #000; height: 5000px;'>5000-pixel box</div><button id='lower_target'>Lower Target</button></body>"></iframe>
-
-<div id="console"></div>
-
-<script>
-description("Tests that scrolling to make an element visible successfully scrolls an iframe.");
-
-if (window.testRunner)
-        testRunner.waitUntilDone();
-
-window.jsTestIsAsync = true;
-
-function runTest() {
-    window.frame = document.getElementById("frame");
-    window.frameWindow = frame.contentWindow;
-    window.frameDoc = frameWindow.document;
-
-    var upperTarget = frameDoc.getElementById("upper_target");
-    var lowerTarget = frameDoc.getElementById("lower_target");
-
-    if (window.accessibilityController) {
-        lowerTarget.focus();
-        var lowerTargetAccessibleObject = accessibilityController.focusedElement;
-        upperTarget.focus();
-        var upperTargetAccessibleObject = accessibilityController.focusedElement;
-    }
-
-    // Reset the initial scroll position (since calling focus() can scroll the page too).
-    frameWindow.scrollTo(0, 0);
-    shouldBe("frameWindow.pageYOffset", "0");
-
-    // Scroll to make lower target visible and check.
-    if (window.accessibilityController)
-        lowerTargetAccessibleObject.scrollToMakeVisible();
-    window.minYOffset = lowerTarget.offsetTop + lowerTarget.offsetHeight - frameWindow.innerHeight;
-    window.maxYOffset = lowerTarget.offsetTop;
-    shouldBe("frameWindow.pageYOffset >= minYOffset", "true");
-    shouldBe("frameWindow.pageYOffset <= maxYOffset", "true");
-
-    // Scroll to make upper target visible and check.
-    if (window.accessibilityController)
-        upperTargetAccessibleObject.scrollToMakeVisible();
-    window.minYOffset = upperTarget.offsetTop + upperTarget.offsetHeight - frameWindow.innerHeight;
-    window.maxYOffset = upperTarget.offsetTop;
-    shouldBe("frameWindow.pageYOffset >= minYOffset", "true");
-    shouldBe("frameWindow.pageYOffset <= maxYOffset", "true");
-
-    finishJSTest();
-}
-
-window.addEventListener('load', function() {
-    setTimeout(runTest, 10);
-}, false);
-
-</script>
-
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-expected.txt b/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-expected.txt
index 3644251..d063af2 100644
--- a/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-expected.txt
+++ b/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-expected.txt
@@ -102,7 +102,7 @@
     var textNode = node.firstChild;
     if (textNode.nodeType != Node.TEXT_NODE)
         throw "Wrong node type: " + textNode;
-    execSetSelectionCommand(textNode, 0, 0);
+    execSetSelectionCommand(textNode, 0, textNode, 0);
 }
 
 function verifyTextSelection(startNode, startOffset, endNode, endOffset)
@@ -159,7 +159,7 @@
 execMoveSelectionForwardByLineCommand();
 execExtendSelectionForwardByLineCommand();
 execExtendSelectionForwardByLineCommand();
-// FIXME: This is wrong.  The pre tags get copied when they shouldn't be. 
+// FIXME: This is wrong.  The pre tags get copied when they shouldn't be.
 // See https://bugs.webkit.org/show_bug.cgi?id=42009
 document.execCommand("indent");
 document.getElementById("results").innerText = "PASSED (did not crash)";
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre.html b/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre.html
index 3cd0c51..eba0a0b 100644
--- a/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre.html
+++ b/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre.html
@@ -30,7 +30,7 @@
     var textNode = node.firstChild;
     if (textNode.nodeType != Node.TEXT_NODE)
         throw "Wrong node type: " + textNode;
-    execSetSelectionCommand(textNode, 0, 0);
+    execSetSelectionCommand(textNode, 0, textNode, 0);
 }
 
 function verifyTextSelection(startNode, startOffset, endNode, endOffset)
@@ -87,7 +87,7 @@
 execMoveSelectionForwardByLineCommand();
 execExtendSelectionForwardByLineCommand();
 execExtendSelectionForwardByLineCommand();
-// FIXME: This is wrong.  The pre tags get copied when they shouldn't be. 
+// FIXME: This is wrong.  The pre tags get copied when they shouldn't be.
 // See https://bugs.webkit.org/show_bug.cgi?id=42009
 document.execCommand("indent");
 document.getElementById("results").innerText = "PASSED (did not crash)";
diff --git a/third_party/WebKit/LayoutTests/editing/pasteboard/copy-image-with-alt-text-expected.txt b/third_party/WebKit/LayoutTests/editing/pasteboard/copy-image-with-alt-text-expected.txt
index 9b4ef23..88ce907 100644
--- a/third_party/WebKit/LayoutTests/editing/pasteboard/copy-image-with-alt-text-expected.txt
+++ b/third_party/WebKit/LayoutTests/editing/pasteboard/copy-image-with-alt-text-expected.txt
@@ -4,10 +4,9 @@
 |   <shadow:root>
 |     <div>
 |       id="inner-editor"
-|       "Here is an emoticon [], some more text [], an empty alt tag [], no alt tag [] and two consecutive images []."
-|       "
-
+|       "Here is an emoticon [], some more text [], an empty alt tag [], no alt tag [] and two consecutive images [].
 "
+|       <br>
 
 Dump of markup 2:
 | <div>
@@ -20,10 +19,9 @@
 |   <shadow:root>
 |     <div>
 |       id="inner-editor"
-|       "Here is an emoticon [:)], some more text [sample text], an empty alt tag [], no alt tag [] and two consecutive images [firstsecond]."
-|       "
-
+|       "Here is an emoticon [:)], some more text [sample text], an empty alt tag [], no alt tag [] and two consecutive images [firstsecond].
 "
+|       <br>
 
 Dump of markup 4:
 | <div>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/type-checking-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/type-checking-expected.txt
new file mode 100644
index 0000000..752c673
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/editing/selection/type-checking-expected.txt
@@ -0,0 +1,21 @@
+PASS selection.collapse(document.body, 0) did not throw exception.
+PASS selection.collapse(null, 0) did not throw exception.
+PASS selection.collapse(undefined, 0) did not throw exception.
+PASS selection.collapse(0, 0) threw exception TypeError: Failed to execute 'collapse' on 'Selection': parameter 1 is not of type 'Node'..
+PASS selection.collapse(window, 0) threw exception TypeError: Failed to execute 'collapse' on 'Selection': parameter 1 is not of type 'Node'..
+PASS selection.setPosition(document.body, 0) did not throw exception.
+PASS selection.setPosition(null, 0) did not throw exception.
+PASS selection.setPosition(undefined, 0) did not throw exception.
+PASS selection.setPosition(0, 0) threw exception TypeError: Failed to execute 'setPosition' on 'Selection': parameter 1 is not of type 'Node'..
+PASS selection.setPosition(window, 0) threw exception TypeError: Failed to execute 'setPosition' on 'Selection': parameter 1 is not of type 'Node'..
+PASS selection.setBaseAndExtent(document.body, 0, document.body, 0) did not throw exception.
+PASS selection.setBaseAndExtent(null, 0, null, 0) did not throw exception.
+PASS selection.setBaseAndExtent(undefined, 0, undefined, 0) did not throw exception.
+PASS selection.setBaseAndExtent(0, 0, null, 0) threw exception TypeError: Failed to execute 'setBaseAndExtent' on 'Selection': parameter 1 is not of type 'Node'..
+PASS selection.setBaseAndExtent(null, 0, 0, 0) threw exception TypeError: Failed to execute 'setBaseAndExtent' on 'Selection': parameter 3 is not of type 'Node'..
+PASS selection.setBaseAndExtent(window, 0, null, 0) threw exception TypeError: Failed to execute 'setBaseAndExtent' on 'Selection': parameter 1 is not of type 'Node'..
+PASS selection.setBaseAndExtent(null, 0, window, 0) threw exception TypeError: Failed to execute 'setBaseAndExtent' on 'Selection': parameter 3 is not of type 'Node'..
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/editing/selection/type-checking.html b/third_party/WebKit/LayoutTests/editing/selection/type-checking.html
new file mode 100644
index 0000000..da265cb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/editing/selection/type-checking.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test.js"></script>
+<body>
+<script>
+window.selection = getSelection();
+
+shouldNotThrow('selection.collapse(document.body, 0)');
+shouldNotThrow('selection.collapse(null, 0)');
+shouldNotThrow('selection.collapse(undefined, 0)');
+shouldThrow('selection.collapse(0, 0)');
+shouldThrow('selection.collapse(window, 0)');
+
+shouldNotThrow('selection.setPosition(document.body, 0)');
+shouldNotThrow('selection.setPosition(null, 0)');
+shouldNotThrow('selection.setPosition(undefined, 0)');
+shouldThrow('selection.setPosition(0, 0)');
+shouldThrow('selection.setPosition(window, 0)');
+
+shouldNotThrow('selection.setBaseAndExtent(document.body, 0, document.body, 0)');
+shouldNotThrow('selection.setBaseAndExtent(null, 0, null, 0)');
+shouldNotThrow('selection.setBaseAndExtent(undefined, 0, undefined, 0)');
+shouldThrow('selection.setBaseAndExtent(0, 0, null, 0)');
+shouldThrow('selection.setBaseAndExtent(null, 0, 0, 0)');
+shouldThrow('selection.setBaseAndExtent(window, 0, null, 0)');
+shouldThrow('selection.setBaseAndExtent(null, 0, window, 0)');
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-x-in-scrolling-div.html b/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-x-in-scrolling-div.html
index 9c7fd46..db79b113 100644
--- a/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-x-in-scrolling-div.html
+++ b/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-x-in-scrolling-div.html
@@ -4,9 +4,9 @@
         <script>
             window.jsTestIsAsync = true;
             var givenScrollTop = 0;
-            var givenScrollLeft = 2;
+            var givenScrollLeft = 2; // When paging, this is ignored. Every event is one page.
             var expectedScrollTop = 0;
-            var expectedScrollLeft = 322;
+            var expectedScrollLeft = 161;
             var event;
             var div;
 
diff --git a/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-xy-in-scrolling-div.html b/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-xy-in-scrolling-div.html
index ad14733..f9db82c 100644
--- a/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-xy-in-scrolling-div.html
+++ b/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-xy-in-scrolling-div.html
@@ -4,9 +4,9 @@
         <script>
             window.jsTestIsAsync = true;
             var givenScrollTop = 1;
-            var givenScrollLeft = 2;
+            var givenScrollLeft = 2; // When paging, this is ignored. Every event is one page.
             var expectedScrollTop = 161;
-            var expectedScrollLeft = 322;
+            var expectedScrollLeft = 161;
             var event;
             var div;
 
diff --git a/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-y-in-scrolling-div.html b/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-y-in-scrolling-div.html
index ef3042649..cad4e13c 100644
--- a/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-y-in-scrolling-div.html
+++ b/third_party/WebKit/LayoutTests/fast/events/platform-wheelevent-paging-y-in-scrolling-div.html
@@ -3,9 +3,9 @@
         <script src="../../resources/js-test.js"></script>
         <script>
             window.jsTestIsAsync = true;
-            var givenScrollTop = 2;
+            var givenScrollTop = 2; // When paging, this is ignored. Every event is one page.
             var givenScrollLeft = 0;
-            var expectedScrollTop = 322; // 2 pages, 161 * 2, see comment in HTML below.
+            var expectedScrollTop = 161;
             var expectedScrollLeft = 0;
             var event;
             var div;
diff --git a/third_party/WebKit/LayoutTests/fast/events/selectstart-by-arrow-keys.html b/third_party/WebKit/LayoutTests/fast/events/selectstart-by-arrow-keys.html
index e5fdeab..e492130 100644
--- a/third_party/WebKit/LayoutTests/fast/events/selectstart-by-arrow-keys.html
+++ b/third_party/WebKit/LayoutTests/fast/events/selectstart-by-arrow-keys.html
@@ -39,7 +39,7 @@
 
     // On Mac, home/end doesn't move caret so manually select " World".
     if (navigator.platform.indexOf('Mac') == 0)
-        window.getSelection().setBaseAndExtent(div.firstChild, div.textContent.indexOf('World'), div.textContent.length);
+        window.getSelection().setBaseAndExtent(div.firstChild, div.textContent.indexOf('World'), div.firstChild, div.textContent.length);
 
     eventSender.keyDown("leftArrow");
     logResult('Check (Left arrow)', 1);
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/gesture/touch-gesture-scroll-page-zoomed.html b/third_party/WebKit/LayoutTests/fast/events/touch/gesture/touch-gesture-scroll-page-zoomed.html
index 804a3b8d..252f07db 100644
--- a/third_party/WebKit/LayoutTests/fast/events/touch/gesture/touch-gesture-scroll-page-zoomed.html
+++ b/third_party/WebKit/LayoutTests/fast/events/touch/gesture/touch-gesture-scroll-page-zoomed.html
@@ -112,7 +112,7 @@
     eventSender.gestureScrollEnd(0, 0);
 
     window.internals.setZoomFactor(2.0);
-    eventSender.gestureScrollBegin(800, 40);
+    eventSender.gestureScrollBegin(799, 40);
     eventSender.gestureScrollUpdate(0, -40);
     eventSender.gestureScrollUpdate(0, -40);
     eventSender.gestureScrollEnd(0, 0);
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/gesture/touch-gesture-scroll-page.html b/third_party/WebKit/LayoutTests/fast/events/touch/gesture/touch-gesture-scroll-page.html
index f09245e..686543c9 100644
--- a/third_party/WebKit/LayoutTests/fast/events/touch/gesture/touch-gesture-scroll-page.html
+++ b/third_party/WebKit/LayoutTests/fast/events/touch/gesture/touch-gesture-scroll-page.html
@@ -104,7 +104,7 @@
 function secondGestureScroll()
 {
     debug("second gesture");
-    eventSender.gestureScrollBegin(800, 40);
+    eventSender.gestureScrollBegin(799, 40);
     eventSender.gestureScrollUpdate(0, -30);
     eventSender.gestureScrollUpdate(0, -30);
     eventSender.gestureScrollEnd(0, 0);
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol-expected.txt
deleted file mode 100644
index f715bfd..0000000
--- a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL TEXTAREA should not remove the last EOL on paste. assert_equals: expected "WH\n" but got "WH"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol.html b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol.html
index 1664f53..5ccc943a 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-value-last-eol.html
@@ -14,10 +14,28 @@
     assert_equals(textarea.value, 'H\nW');
     textarea.setSelectionRange(2, 3); // "W"
     document.execCommand('cut');
+    assert_equals(textarea.value, 'H\n');
     textarea.setSelectionRange(0, 0);
     document.execCommand('paste');
-    // TODO(tkent): The following assertion fails now. crbug.com/522144.
     assert_equals(textarea.value, 'WH\n');
 }, 'TEXTAREA should not remove the last EOL on paste.');
+
+test(function() {
+    var textarea1 = document.createElement('textarea');
+    document.body.appendChild(textarea1);
+    textarea1.focus();
+    textarea1.addEventListener('copy', function(event) {
+        event.clipboardData.setData('text', 'foo\n');
+        event.preventDefault();
+    });
+    document.execCommand('copy');
+
+    // Use another TEXAREA.  We need a clean one.
+    var textarea2 = document.createElement('textarea');
+    document.body.appendChild(textarea2);
+    textarea2.focus();
+    document.execCommand('paste');
+    assert_equals(textarea2.value, 'foo\n');
+}, 'Pasting text ending \\n should not add another \\n.');
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/fast/images/resources/cropped_mandrill.jpg b/third_party/WebKit/LayoutTests/fast/images/resources/cropped_mandrill.jpg
new file mode 100644
index 0000000..e1a233ad
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/images/resources/cropped_mandrill.jpg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/intersection-observer/iframe-cross-origin.html b/third_party/WebKit/LayoutTests/http/tests/intersection-observer/iframe-cross-origin.html
index 0132d6d5..3324515 100644
--- a/third_party/WebKit/LayoutTests/http/tests/intersection-observer/iframe-cross-origin.html
+++ b/third_party/WebKit/LayoutTests/http/tests/intersection-observer/iframe-cross-origin.html
@@ -61,11 +61,7 @@
 }
 
 window.addEventListener("message", handleMessage);
-
 iframe.onload = function() {
-  // See LayoutTests/intersection-observer/README for explanation of double RAF.
-  requestAnimationFrame(() => {
-      requestAnimationFrame(() => { iframe.contentWindow.postMessage("", "*") })
-  });
-}
+  iframe.contentWindow.postMessage("", "*")
+};
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/intersection-observer/resources/cross-origin-subframe.html b/third_party/WebKit/LayoutTests/http/tests/intersection-observer/resources/cross-origin-subframe.html
index eda791fa..d2a40dd 100644
--- a/third_party/WebKit/LayoutTests/http/tests/intersection-observer/resources/cross-origin-subframe.html
+++ b/third_party/WebKit/LayoutTests/http/tests/intersection-observer/resources/cross-origin-subframe.html
@@ -14,54 +14,60 @@
 // Instead of RAF-ing, we just post an empty message to the parent window, which will
 // RAF when it is received, and then send us a message to cause the next step to run.
 
+function observer_callback(changes) {
+  for (var i in changes)
+    entries.push(changes[i]);
+}
+
 // Use a rootMargin here, and verify it does NOT get applied for the cross-origin case.
-var observer = new IntersectionObserver(
-    changes => { entries = entries.concat(changes) },
-    { rootMargin: "7px" }
-);
+var observer = new IntersectionObserver(observer_callback, {rootMargin: "7px"});
 observer.observe(target);
 
 function step0() {
-  entries = entries.concat(observer.takeRecords());
-  nextStep = step1;
-  port.postMessage({actual: entries.map(entryToJson), expected: []}, "*");
-  entries = [];
-  port.postMessage({scrollTo: 200}, "*");
+  setTimeout(function() {
+    nextStep = step1;
+    port.postMessage({actual: entries.map(entryToJson), expected: []}, "*");
+    entries = [];
+    port.postMessage({scrollTo: 200}, "*");
+  });
 }
 
 function step1() {
-  entries = entries.concat(observer.takeRecords());
-  port.postMessage({actual: entries.map(entryToJson), expected: []}, "*");
-  entries = [];
-  scroller.scrollTop = 250;
-  nextStep = step2;
-  port.postMessage({}, "*");
+  setTimeout(function() {
+    port.postMessage({actual: entries.map(entryToJson), expected: []}, "*");
+    entries = [];
+    scroller.scrollTop = 250;
+    nextStep = step2;
+    port.postMessage({}, "*");
+  });
 }
 
 function step2() {
-  entries = entries.concat(observer.takeRecords());
-  var expected = [{
-    boundingClientRect: coordinatesToClientRectJson(-42, 108, 58, 8),
-    intersectionRect: coordinatesToClientRectJson(0, 108, 58, 8),
-    rootBounds: "null",
-    target: target.id
-  }];
-  port.postMessage({actual: entries.map(entryToJson), expected: expected}, "*");
-  entries = [];
-  nextStep = step3;
-  port.postMessage({scrollTo: 100}, "*");
+  setTimeout(function() {
+    var expected = [{
+      boundingClientRect: coordinatesToClientRectJson(-42, 108, 58, 8),
+      intersectionRect: coordinatesToClientRectJson(0, 108, 58, 8),
+      rootBounds: "null",
+      target: target.id
+    }];
+    port.postMessage({actual: entries.map(entryToJson), expected: expected}, "*");
+    entries = [];
+    nextStep = step3;
+    port.postMessage({scrollTo: 100}, "*");
+  });
 }
 
 function step3() {
-  entries = entries.concat(observer.takeRecords());
-  var expected = [{
-    boundingClientRect: coordinatesToClientRectJson(-42, 108, 58, 8),
-    intersectionRect: coordinatesToClientRectJson(0, 0, 0, 0),
-    rootBounds: "null",
-    target: target.id
-  }];
-  port.postMessage({actual: entries.map(entryToJson), expected: expected}, "*");
-  port.postMessage({DONE: 1}, "*");
+  setTimeout(function() {
+    var expected = [{
+      boundingClientRect: coordinatesToClientRectJson(-42, 108, 58, 8),
+      intersectionRect: coordinatesToClientRectJson(0, 0, 0, 0),
+      rootBounds: "null",
+      target: target.id
+    }];
+    port.postMessage({actual: entries.map(entryToJson), expected: expected}, "*");
+    port.postMessage({DONE: 1}, "*");
+  });
 }
 
 function handleMessage(event)
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-expected.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-expected.html
index e6518bc9..b0287c2 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-expected.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-expected.html
@@ -26,7 +26,7 @@
         <div class="item">456</div>
         <div class="item">def</div>
         <div class="item">789</div>
-        <div class="item">ghi</div>
+        <div class="item">stu</div>
     </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-expected.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-expected.html
index e6518bc9..b0287c2 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-expected.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-expected.html
@@ -26,7 +26,7 @@
         <div class="item">456</div>
         <div class="item">def</div>
         <div class="item">789</div>
-        <div class="item">ghi</div>
+        <div class="item">stu</div>
     </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-expected.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-expected.html
index e6518bc9..b0287c2 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-expected.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-expected.html
@@ -26,7 +26,7 @@
         <div class="item">456</div>
         <div class="item">def</div>
         <div class="item">789</div>
-        <div class="item">ghi</div>
+        <div class="item">stu</div>
     </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-reverse-expected.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-reverse-expected.html
index e6518bc9..b0287c2 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-reverse-expected.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-reverse-expected.html
@@ -26,7 +26,7 @@
         <div class="item">456</div>
         <div class="item">def</div>
         <div class="item">789</div>
-        <div class="item">ghi</div>
+        <div class="item">stu</div>
     </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-reverse.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-reverse.html
index 074d4833..5a5557a 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-reverse.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap-reverse.html
@@ -32,19 +32,19 @@
 <body>
     <p>The test passes if you see a tall green box with pairs of the digits 1-9 and a-i listed right to left in two columns.</p>
     <div class="container">
-        <div class="item">i</div>
+        <div class="item">u</div>
         <div class="item">9</div>
         <div class="item">f</div>
         <div class="item">6</div>
         <div class="item">c</div>
         <div class="item">3</div>
-        <div class="item">h</div>
+        <div class="item">t</div>
         <div class="item">8</div>
         <div class="item">e</div>
         <div class="item">5</div>
         <div class="item">b</div>
         <div class="item">2</div>
-        <div class="item">g</div>
+        <div class="item">s</div>
         <div class="item">7</div>
         <div class="item">d</div>
         <div class="item">4</div>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap.html
index b4f8a3b..533af37 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse-wrap.html
@@ -32,19 +32,19 @@
 <body>
     <p>The test passes if you see a tall green box with pairs of the digits 1-9 and a-i listed right to left in two columns.</p>
     <div class="container">
-        <div class="item">g</div>
+        <div class="item">s</div>
         <div class="item">7</div>
         <div class="item">d</div>
         <div class="item">4</div>
         <div class="item">a</div>
         <div class="item">1</div>
-        <div class="item">h</div>
+        <div class="item">t</div>
         <div class="item">8</div>
         <div class="item">e</div>
         <div class="item">5</div>
         <div class="item">b</div>
         <div class="item">2</div>
-        <div class="item">i</div>
+        <div class="item">u</div>
         <div class="item">9</div>
         <div class="item">f</div>
         <div class="item">6</div>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse.html
index f5d523d..edc92760 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-reverse.html
@@ -29,7 +29,7 @@
 <body>
     <p>The test passes if you see a tall green box with pairs of the digits 1-9 and a-i listed right to left in two columns.</p>
     <div class="container">
-        <div class="item">ghi</div>
+        <div class="item">stu</div>
         <div class="item">789</div>
         <div class="item">def</div>
         <div class="item">456</div>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-expected.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-expected.html
index e6518bc9..b0287c2 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-expected.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-expected.html
@@ -26,7 +26,7 @@
         <div class="item">456</div>
         <div class="item">def</div>
         <div class="item">789</div>
-        <div class="item">ghi</div>
+        <div class="item">stu</div>
     </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-reverse-expected.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-reverse-expected.html
index e6518bc9..b0287c2 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-reverse-expected.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-reverse-expected.html
@@ -26,7 +26,7 @@
         <div class="item">456</div>
         <div class="item">def</div>
         <div class="item">789</div>
-        <div class="item">ghi</div>
+        <div class="item">stu</div>
     </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-reverse.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-reverse.html
index 86465bad..b4c8b2e 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-reverse.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap-reverse.html
@@ -37,19 +37,19 @@
         <div class="item">6</div>
         <div class="item">f</div>
         <div class="item">9</div>
-        <div class="item">i</div>
+        <div class="item">u</div>
         <div class="item">2</div>
         <div class="item">b</div>
         <div class="item">5</div>
         <div class="item">e</div>
         <div class="item">8</div>
-        <div class="item">h</div>
+        <div class="item">t</div>
         <div class="item">1</div>
         <div class="item">a</div>
         <div class="item">4</div>
         <div class="item">d</div>
         <div class="item">7</div>
-        <div class="item">g</div>
+        <div class="item">s</div>
     </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap.html
index 0277c838..4924e92 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column-wrap.html
@@ -37,19 +37,19 @@
         <div class="item">4</div>
         <div class="item">d</div>
         <div class="item">7</div>
-        <div class="item">g</div>
+        <div class="item">s</div>
         <div class="item">2</div>
         <div class="item">b</div>
         <div class="item">5</div>
         <div class="item">e</div>
         <div class="item">8</div>
-        <div class="item">h</div>
+        <div class="item">t</div>
         <div class="item">3</div>
         <div class="item">c</div>
         <div class="item">6</div>
         <div class="item">f</div>
         <div class="item">9</div>
-        <div class="item">i</div>
+        <div class="item">u</div>
     </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column.html
index 3a4fdb6..7bc14a3 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column.html
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/css-flexbox-column.html
@@ -34,7 +34,7 @@
         <div class="item">456</div>
         <div class="item">def</div>
         <div class="item">789</div>
-        <div class="item">ghi</div>
+        <div class="item">stu</div>
     </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-001-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-001-expected.xht
new file mode 100644
index 0000000..05a1379
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-001-expected.xht
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>CSS Reftest Reference</title>
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
+  <style type="text/css"><![CDATA[
+  div
+  {
+  background-color: green;
+  height: 100px;
+  width: 100px;
+  }
+  ]]></style>
+ </head>
+ <body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+ </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-001.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-001.html
new file mode 100644
index 0000000..b6d4ea5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-001.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Flexible Box Test: Aspect ratio handling of images</title>
+        <link rel="author" title="Google Inc." href="http://www.google.com/" />
+        <link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#hypothetical-main-size" />
+        <link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+        <style type="text/css">
+            #reference-overlapped-red {
+                position: absolute;
+                background-color: red;
+                width: 100px;
+                height: 100px;
+                z-index: -1;
+            }
+
+            #constrained-flex {
+                display: flex;
+                flex-direction: column;
+                height: 10px;
+            }
+
+            img {
+                min-width: 0;
+                min-height: 0;
+                flex: none;
+                width: 100px;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+        <div id="reference-overlapped-red"></div>
+        <div id="constrained-flex">
+            <img id="test-flex-item-overlapping-green" src="support/200x200-green.png" />
+        </div>
+    </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-002-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-002-expected.xht
new file mode 100644
index 0000000..05a1379
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-002-expected.xht
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>CSS Reftest Reference</title>
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
+  <style type="text/css"><![CDATA[
+  div
+  {
+  background-color: green;
+  height: 100px;
+  width: 100px;
+  }
+  ]]></style>
+ </head>
+ <body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+ </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-002.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-002.html
new file mode 100644
index 0000000..7653448
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-002.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Flexible Box Test: Aspect ratio handling of images</title>
+        <link rel="author" title="Google Inc." href="http://www.google.com/" />
+        <link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#algo-cross-item" />
+        <link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+        <meta name="assert" content="Test that we compute the correct aspect-ratio based cross size when a height is specified" />
+        <style type="text/css">
+            #reference-overlapped-red {
+                position: absolute;
+                background-color: red;
+                width: 100px;
+                height: 100px;
+                z-index: -1;
+            }
+
+            #constrained-flex {
+                display: flex;
+                flex-direction: column;
+                height: 10px;
+            }
+
+            img {
+                min-width: 0;
+                min-height: 0;
+                flex: none;
+                height: 100px;
+                align-self: flex-start;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+        <div id="reference-overlapped-red"></div>
+        <div id="constrained-flex">
+            <img id="test-flex-item-overlapping-green" src="support/200x200-green.png" />
+        </div>
+    </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-003-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-003-expected.xht
new file mode 100644
index 0000000..05a1379
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-003-expected.xht
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>CSS Reftest Reference</title>
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
+  <style type="text/css"><![CDATA[
+  div
+  {
+  background-color: green;
+  height: 100px;
+  width: 100px;
+  }
+  ]]></style>
+ </head>
+ <body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+ </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-003.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-003.html
new file mode 100644
index 0000000..be40dcb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-column-003.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Flexible Box Test: Aspect ratio handling of images</title>
+        <link rel="author" title="Google Inc." href="http://www.google.com/" />
+        <link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#algo-cross-item" />
+        <link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+        <meta name="assert" content="Test that we compute the correct aspect-ratio based cross size when a flex-basis is specified" />
+        <style type="text/css">
+            #reference-overlapped-red {
+                position: absolute;
+                background-color: red;
+                width: 100px;
+                height: 100px;
+                z-index: -1;
+            }
+
+            #constrained-flex {
+                display: flex;
+                flex-direction: column;
+                height: 10px;
+            }
+
+            img {
+                min-width: 0;
+                min-height: 0;
+                flex: none;
+                flex-basis: 100px;
+                align-self: flex-start;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+        <div id="reference-overlapped-red"></div>
+        <div id="constrained-flex">
+            <img id="test-flex-item-overlapping-green" src="support/200x200-green.png" />
+        </div>
+    </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-001-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-001-expected.xht
new file mode 100644
index 0000000..05a1379
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-001-expected.xht
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>CSS Reftest Reference</title>
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
+  <style type="text/css"><![CDATA[
+  div
+  {
+  background-color: green;
+  height: 100px;
+  width: 100px;
+  }
+  ]]></style>
+ </head>
+ <body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+ </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-001.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-001.html
new file mode 100644
index 0000000..63d7766
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-001.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Flexible Box Test: Aspect ratio handling of images</title>
+        <link rel="author" title="Google Inc." href="http://www.google.com/" />
+        <link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#hypothetical-main-size" />
+        <link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+        <style type="text/css">
+            #reference-overlapped-red {
+                position: absolute;
+                background-color: red;
+                width: 100px;
+                height: 100px;
+                z-index: -1;
+            }
+
+            #constrained-flex {
+                display: flex;
+                width: 10px;
+            }
+
+            img {
+                min-width: 0;
+                min-height: 0;
+                flex: none;
+                height: 100px;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+        <div id="reference-overlapped-red"></div>
+        <div id="constrained-flex">
+            <img id="test-flex-item-overlapping-green" src="support/200x200-green.png" />
+        </div>
+    </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-002-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-002-expected.xht
new file mode 100644
index 0000000..05a1379
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-002-expected.xht
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>CSS Reftest Reference</title>
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
+  <style type="text/css"><![CDATA[
+  div
+  {
+  background-color: green;
+  height: 100px;
+  width: 100px;
+  }
+  ]]></style>
+ </head>
+ <body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+ </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-002.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-002.html
new file mode 100644
index 0000000..89a87e58
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-002.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Flexible Box Test: Aspect ratio handling of images</title>
+        <link rel="author" title="Google Inc." href="http://www.google.com/" />
+        <link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#algo-cross-item" />
+        <link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+        <meta name="assert" content="Test that we compute the correct aspect-ratio based cross size when a width is specified" />
+        <style type="text/css">
+            #reference-overlapped-red {
+                position: absolute;
+                background-color: red;
+                width: 100px;
+                height: 100px;
+                z-index: -1;
+            }
+
+            #constrained-flex {
+                display: flex;
+                width: 10px;
+            }
+
+            img {
+                min-width: 0;
+                min-height: 0;
+                flex: none;
+                width: 100px;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+        <div id="reference-overlapped-red"></div>
+        <div id="constrained-flex">
+            <img id="test-flex-item-overlapping-green" src="support/200x200-green.png" />
+        </div>
+    </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-003-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-003-expected.xht
new file mode 100644
index 0000000..05a1379
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-003-expected.xht
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>CSS Reftest Reference</title>
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
+  <style type="text/css"><![CDATA[
+  div
+  {
+  background-color: green;
+  height: 100px;
+  width: 100px;
+  }
+  ]]></style>
+ </head>
+ <body>
+  <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+  <div></div>
+ </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-003.html b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-003.html
new file mode 100644
index 0000000..3cfcd2c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-flexbox-1/flex-aspect-ratio-img-row-003.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>CSS Flexible Box Test: Aspect ratio handling of images</title>
+        <link rel="author" title="Google Inc." href="http://www.google.com/" />
+        <link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#algo-cross-item" />
+        <link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+        <meta name="assert" content="Test that we compute the correct aspect-ratio based cross size when a flex-basis is specified" />
+        <style type="text/css">
+            #reference-overlapped-red {
+                position: absolute;
+                background-color: red;
+                width: 100px;
+                height: 100px;
+                z-index: -1;
+            }
+
+            #constrained-flex {
+                display: flex;
+                width: 10px;
+            }
+
+            img {
+                min-width: 0;
+                min-height: 0;
+                flex: none;
+                flex-basis: 100px;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+        <div id="reference-overlapped-red"></div>
+        <div id="constrained-flex">
+            <img id="test-flex-item-overlapping-green" src="support/200x200-green.png" />
+        </div>
+    </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-copy-treeoutline.html b/third_party/WebKit/LayoutTests/inspector/console/console-copy-treeoutline.html
index e6e7706..be3fafdf5 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-copy-treeoutline.html
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-copy-treeoutline.html
@@ -28,7 +28,7 @@
             viewport.forceScrollItemToBeFirst(0);
 
             // Set some initial selection in console.
-            var base = consoleView.itemElement(0);
+            var base = consoleView.itemElement(0).element();
             window.getSelection().setBaseAndExtent(base, 0, base, 1);
 
             // Try to select all messages.
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-viewport-selection.html b/third_party/WebKit/LayoutTests/inspector/console/console-viewport-selection.html
index d1f84d9..1eedad3 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-viewport-selection.html
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-viewport-selection.html
@@ -171,8 +171,8 @@
             viewport.forceScrollItemToBeFirst(0);
 
             // Set some initial selection in console.
-            var base = consoleView.itemElement(messagesCount - 2);
-            var extent = consoleView.itemElement(messagesCount - 1);
+            var base = consoleView.itemElement(messagesCount - 2).element();
+            var extent = consoleView.itemElement(messagesCount - 1).element();
             window.getSelection().setBaseAndExtent(base, 0, extent, 0);
 
             // Try to select all messages.
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/README b/third_party/WebKit/LayoutTests/intersection-observer/README
deleted file mode 100644
index 4dad2f33..0000000
--- a/third_party/WebKit/LayoutTests/intersection-observer/README
+++ /dev/null
@@ -1,29 +0,0 @@
-All of the IntersectionObserver tests feature the following idiom:
-
-<script>
-var observer = new IntersectionObserver(...)
-function test_function() {
-  var entries = observer.takeRecords();
-  // Verify entries
-}
-onload = function() {
-  observer.observe(target);
-  requestAnimationFrame(() => { requestAnimationFrame(test_function) });
-}
-
-
-Subsequent steps in the test use a single RAF to give the observer a chance to
-generate notifications, but the double RAF is required in the onload handler.
-Here's the chain of events:
-
-- onload
-  - observer.observe()
-  - First RAF handler is registered
-- BeginFrame
-  - RAF handlers run
-    - Second RAF handler is registered 
-  - UpdateAllLifecyclePhases
-    - IntersectionObserver generates notifications
-- BeginFrame
-  - RAF handlers run
-    - Second RAF handler verifies observer notifications.
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/containing-block.html b/third_party/WebKit/LayoutTests/intersection-observer/containing-block.html
index 819ec5fa..f7db8fb 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/containing-block.html
+++ b/third_party/WebKit/LayoutTests/intersection-observer/containing-block.html
@@ -19,79 +19,81 @@
 </div>
 
 <script>
-description("Test that no notifications are generated when root is not in the containing block chain of target.");
-var root = document.getElementById("root");
-var target = document.getElementById("target");
-var entries = [];
+  description("Test that no notifications are generated when root is not in the containing block chain of target.");
+  var root = document.getElementById("root");
+  var target = document.getElementById("target");
+  var entries = [];
 
-var observer = new IntersectionObserver(
-    changes => { entries = entries.concat(changes) },
-    { root: root }
-);
-
-onload = function() {
-  observer.observe(target);
-  shouldBeEqualToNumber("entries.length", 0);
-  target.style.top = "10px";
-  // See README for explanation of double RAF.
-  requestAnimationFrame(() => { requestAnimationFrame(step1) });
-};
-
-function step1() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 1);
-  if (entries.length > 0) {
-    shouldBeEqualToNumber("entries[0].boundingClientRect.left", 58);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.right", 158);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.top", 18);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 118);
-    shouldBeEqualToNumber("entries[0].intersectionRect.left", 58);
-    shouldBeEqualToNumber("entries[0].intersectionRect.right", 158);
-    shouldBeEqualToNumber("entries[0].intersectionRect.top", 18);
-    shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 118);
-    shouldBeEqualToNumber("entries[0].rootBounds.left", 8);
-    shouldBeEqualToNumber("entries[0].rootBounds.right", 193);
-    shouldBeEqualToNumber("entries[0].rootBounds.top", 8);
-    shouldBeEqualToNumber("entries[0].rootBounds.bottom", 208);
-    shouldEvaluateToSameObject("entries[0].target", target);
+  function observer_callback(changes) {
+    changes.forEach(function(e) { entries.push(e) });
   }
-  target.style.top = "250px";
-  requestAnimationFrame(step2);
-}
+  new IntersectionObserver(observer_callback, {root: root}).observe(target);
 
-function step2() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 2);
-  if (entries.length > 1) {
-    shouldBeEqualToNumber("entries[1].boundingClientRect.left", 58);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.right", 158);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.top", 258);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 358);
-    shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.left", 8);
-    shouldBeEqualToNumber("entries[1].rootBounds.right", 193);
-    shouldBeEqualToNumber("entries[1].rootBounds.top", 8);
-    shouldBeEqualToNumber("entries[1].rootBounds.bottom", 208);
-    shouldEvaluateToSameObject("entries[1].target", target);
+  function step0() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 0);
+      target.style.top = "10px";
+      requestAnimationFrame(step1);
+    });
   }
-  root.style.position = "static";
-  target.style.top = "10px";
-  requestAnimationFrame(step3);
-}
 
-function step3() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 2);
-  target.style.top = "250px";
-  requestAnimationFrame(step4);
-}
+  function step1() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 1);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.left", 58);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.right", 158);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.top", 18);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 118);
+      shouldBeEqualToNumber("entries[0].intersectionRect.left", 58);
+      shouldBeEqualToNumber("entries[0].intersectionRect.right", 158);
+      shouldBeEqualToNumber("entries[0].intersectionRect.top", 18);
+      shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 118);
+      shouldBeEqualToNumber("entries[0].rootBounds.left", 8);
+      shouldBeEqualToNumber("entries[0].rootBounds.right", 193);
+      shouldBeEqualToNumber("entries[0].rootBounds.top", 8);
+      shouldBeEqualToNumber("entries[0].rootBounds.bottom", 208);
+      shouldEvaluateToSameObject("entries[0].target", target);
+      target.style.top = "250px";
+      requestAnimationFrame(step2);
+    });
+  }
 
-function step4() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 2);
-  finishJSTest();
-}
+  function step2() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 2);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.left", 58);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.right", 158);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.top", 258);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 358);
+      shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.left", 8);
+      shouldBeEqualToNumber("entries[1].rootBounds.right", 193);
+      shouldBeEqualToNumber("entries[1].rootBounds.top", 8);
+      shouldBeEqualToNumber("entries[1].rootBounds.bottom", 208);
+      shouldEvaluateToSameObject("entries[1].target", target);
+      root.style.position = "static";
+      target.style.top = "10px";
+      requestAnimationFrame(step3);
+    });
+  }
+
+  function step3() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 2);
+      target.style.top = "250px";
+      requestAnimationFrame(step4);
+    });
+  }
+
+  function step4() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 2);
+      finishJSTest();
+    });
+  }
+
+  step0();
 </script>
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/iframe-no-root-expected.txt b/third_party/WebKit/LayoutTests/intersection-observer/iframe-no-root-expected.txt
index a744f4e..a8fc7831 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/iframe-no-root-expected.txt
+++ b/third_party/WebKit/LayoutTests/intersection-observer/iframe-no-root-expected.txt
@@ -5,7 +5,6 @@
 
 PASS entries.length is 0
 PASS entries.length is 0
-PASS entries.length is 0
 PASS entries.length is 1
 PASS entries[0].boundingClientRect.left is 8
 PASS entries[0].boundingClientRect.right is 108
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/iframe-no-root.html b/third_party/WebKit/LayoutTests/intersection-observer/iframe-no-root.html
index 134b645..912e286f 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/iframe-no-root.html
+++ b/third_party/WebKit/LayoutTests/intersection-observer/iframe-no-root.html
@@ -8,76 +8,81 @@
 <script>
 description("Simple intersection observer test with no explicit root and target in an iframe.");
 var entries = [];
-var observer = new IntersectionObserver(changes => { entries = entries.concat(changes) }, {});
 var targetIframe = document.getElementById("target-iframe");
-var target;
-var iframeScroller;
 
 targetIframe.onload = function() {
-  target = targetIframe.contentDocument.getElementById("target");
-  iframeScroller = targetIframe.contentDocument.scrollingElement;
+  var target = targetIframe.contentDocument.getElementById("target");
+  var iframeScroller = targetIframe.contentDocument.scrollingElement;
+
+  observer_callback = function(changes) {
+    for (var i in changes)
+      entries.push(changes[i]);
+  };
+  var observer = new IntersectionObserver(observer_callback, {});
   observer.observe(target);
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  // See README for explanation of double RAF.
-  requestAnimationFrame(() => { requestAnimationFrame(step0) });
-}
 
-function step0() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  document.scrollingElement.scrollTop = 200;
-  requestAnimationFrame(step1);
-}
-
-function step1() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  iframeScroller.scrollTop = 250;
-  requestAnimationFrame(step2);
-}
-
-function step2() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 1);
-  if (entries.length > 0) {
-    shouldBeEqualToNumber("entries[0].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.top", -42);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 58);
-    shouldBeEqualToNumber("entries[0].intersectionRect.left", 8);
-    shouldBeEqualToNumber("entries[0].intersectionRect.right", 108);
-    shouldBeEqualToNumber("entries[0].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 58);
-    shouldBeEqualToNumber("entries[0].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[0].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[0].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[0].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[0].target", target);
+  function step0() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 0);
+      document.scrollingElement.scrollTop = 200;
+      requestAnimationFrame(step1);
+    });
   }
-  document.scrollingElement.scrollTop = 100;
-  requestAnimationFrame(step3);
-}
 
-function step3() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 2);
-  if (entries.length > 1) {
-    shouldBeEqualToNumber("entries[1].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.top", -42);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 58);
-    shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[1].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[1].target", target);
+  function step1() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 0);
+      iframeScroller.scrollTop = 250;
+      requestAnimationFrame(step2);
+    });
   }
-  finishJSTest();
-  document.scrollingElement.scrollTop = 0;
+
+  function step2() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 1);
+      if (entries.length > 0) {
+        shouldBeEqualToNumber("entries[0].boundingClientRect.left", 8);
+        shouldBeEqualToNumber("entries[0].boundingClientRect.right", 108);
+        shouldBeEqualToNumber("entries[0].boundingClientRect.top", -42);
+        shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 58);
+        shouldBeEqualToNumber("entries[0].intersectionRect.left", 8);
+        shouldBeEqualToNumber("entries[0].intersectionRect.right", 108);
+        shouldBeEqualToNumber("entries[0].intersectionRect.top", 0);
+        shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 58);
+        shouldBeEqualToNumber("entries[0].rootBounds.left", 0);
+        shouldBeEqualToNumber("entries[0].rootBounds.right", 785);
+        shouldBeEqualToNumber("entries[0].rootBounds.top", 0);
+        shouldBeEqualToNumber("entries[0].rootBounds.bottom", 600);
+        shouldEvaluateToSameObject("entries[0].target", target);
+      }
+      document.scrollingElement.scrollTop = 100;
+      requestAnimationFrame(step3);
+    });
+  }
+
+  function step3() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 2);
+      if (entries.length > 1) {
+        shouldBeEqualToNumber("entries[1].boundingClientRect.left", 8);
+        shouldBeEqualToNumber("entries[1].boundingClientRect.right", 108);
+        shouldBeEqualToNumber("entries[1].boundingClientRect.top", -42);
+        shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 58);
+        shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
+        shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
+        shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
+        shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
+        shouldBeEqualToNumber("entries[1].rootBounds.left", 0);
+        shouldBeEqualToNumber("entries[1].rootBounds.right", 785);
+        shouldBeEqualToNumber("entries[1].rootBounds.top", 0);
+        shouldBeEqualToNumber("entries[1].rootBounds.bottom", 600);
+        shouldEvaluateToSameObject("entries[1].target", target);
+      }
+      finishJSTest();
+      document.scrollingElement.scrollTop = 0;
+    });
+  }
+
+  step0();
 }
 </script>
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/multiple-thresholds-expected.txt b/third_party/WebKit/LayoutTests/intersection-observer/multiple-thresholds-expected.txt
index 512532f..b3d7f60 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/multiple-thresholds-expected.txt
+++ b/third_party/WebKit/LayoutTests/intersection-observer/multiple-thresholds-expected.txt
@@ -4,7 +4,6 @@
 
 
 PASS entries.length is 0
-PASS entries.length is 0
 PASS entries.length is 1
 PASS entries[0].boundingClientRect.left is 8
 PASS entries[0].boundingClientRect.right is 108
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/multiple-thresholds.html b/third_party/WebKit/LayoutTests/intersection-observer/multiple-thresholds.html
index cee4e94..94db094 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/multiple-thresholds.html
+++ b/third_party/WebKit/LayoutTests/intersection-observer/multiple-thresholds.html
@@ -6,202 +6,194 @@
 <div style="width:100%; height:700px;"></div>
 
 <script>
-description("Intersection observer test with multiple thresholds.");
-var target = document.getElementById("target");
-var entries = [];
-var observer = new IntersectionObserver(
-    changes => { entries = entries.concat(changes) },
-    { threshold: [0, 0.25, 0.5, 0.75, 1] }
-);
+  description("Intersection observer test with multiple thresholds.");
+  var target = document.getElementById("target");
+  var entries = [];
 
-onload = function() {
+  observer_callback = function(changes) {
+    for (var i in changes)
+      entries.push(changes[i]);
+  };
+  var observer = new IntersectionObserver(observer_callback, {
+    threshold: [0, 0.25, 0.5, 0.75, 1]
+  });
   observer.observe(target);
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  // See README for explanation of double RAF.
-  requestAnimationFrame(() => { requestAnimationFrame(step0) });
-}
 
-function step0() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  document.scrollingElement.scrollTop = 120;
-  requestAnimationFrame(step1);
-}
-
-function step1() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 1);
-  if (entries.length > 0) {
-    shouldBeEqualToNumber("entries[0].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.top", 588);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 688);
-    shouldBeEqualToNumber("entries[0].intersectionRect.left", 8);
-    shouldBeEqualToNumber("entries[0].intersectionRect.right", 108);
-    shouldBeEqualToNumber("entries[0].intersectionRect.top", 588);
-    shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 600);
-    shouldBeEqualToNumber("entries[0].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[0].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[0].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[0].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[0].target", target);
+  function step0() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 0);
+      document.scrollingElement.scrollTop = 120;
+      requestAnimationFrame(step1);
+    });
   }
-  document.scrollingElement.scrollTop = 160;
-  requestAnimationFrame(step2);
-}
 
-function step2() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 2);
-  if (entries.length > 1) {
-    shouldBeEqualToNumber("entries[1].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.top", 548);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 648);
-    shouldBeEqualToNumber("entries[1].intersectionRect.left", 8);
-    shouldBeEqualToNumber("entries[1].intersectionRect.right", 108);
-    shouldBeEqualToNumber("entries[1].intersectionRect.top", 548);
-    shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 600);
-    shouldBeEqualToNumber("entries[1].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[1].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[1].target", target);
+  function step1() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 1);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.right", 108);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.top", 588);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 688);
+      shouldBeEqualToNumber("entries[0].intersectionRect.left", 8);
+      shouldBeEqualToNumber("entries[0].intersectionRect.right", 108);
+      shouldBeEqualToNumber("entries[0].intersectionRect.top", 588);
+      shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 600);
+      shouldBeEqualToNumber("entries[0].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[0].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[0].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[0].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[0].target", target);
+      document.scrollingElement.scrollTop = 160;
+      requestAnimationFrame(step2);
+    });
   }
-  document.scrollingElement.scrollTop = 200;
-  requestAnimationFrame(step3);
-}
 
-function step3() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 3);
-  if (entries.length > 2) {
-    shouldBeEqualToNumber("entries[2].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[2].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[2].boundingClientRect.top", 508);
-    shouldBeEqualToNumber("entries[2].boundingClientRect.bottom", 608);
-    shouldBeEqualToNumber("entries[2].intersectionRect.left", 8);
-    shouldBeEqualToNumber("entries[2].intersectionRect.right", 108);
-    shouldBeEqualToNumber("entries[2].intersectionRect.top", 508);
-    shouldBeEqualToNumber("entries[2].intersectionRect.bottom", 600);
-    shouldBeEqualToNumber("entries[2].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[2].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[2].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[2].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[2].target", target);
+  function step2() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 2);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.right", 108);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.top", 548);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 648);
+      shouldBeEqualToNumber("entries[1].intersectionRect.left", 8);
+      shouldBeEqualToNumber("entries[1].intersectionRect.right", 108);
+      shouldBeEqualToNumber("entries[1].intersectionRect.top", 548);
+      shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 600);
+      shouldBeEqualToNumber("entries[1].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[1].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[1].target", target);
+      document.scrollingElement.scrollTop = 200;
+      requestAnimationFrame(step3);
+    });
   }
-  document.scrollingElement.scrollTop = 240;
-  requestAnimationFrame(step4);
-}
 
-function step4() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 4);
-  if (entries.length > 3) {
-    shouldBeEqualToNumber("entries[3].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[3].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[3].boundingClientRect.top", 468);
-    shouldBeEqualToNumber("entries[3].boundingClientRect.bottom", 568);
-    shouldBeEqualToNumber("entries[3].intersectionRect.left", 8);
-    shouldBeEqualToNumber("entries[3].intersectionRect.right", 108);
-    shouldBeEqualToNumber("entries[3].intersectionRect.top", 468);
-    shouldBeEqualToNumber("entries[3].intersectionRect.bottom", 568);
-    shouldBeEqualToNumber("entries[3].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[3].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[3].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[3].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[3].target", target);
+  function step3() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 3);
+      shouldBeEqualToNumber("entries[2].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[2].boundingClientRect.right", 108);
+      shouldBeEqualToNumber("entries[2].boundingClientRect.top", 508);
+      shouldBeEqualToNumber("entries[2].boundingClientRect.bottom", 608);
+      shouldBeEqualToNumber("entries[2].intersectionRect.left", 8);
+      shouldBeEqualToNumber("entries[2].intersectionRect.right", 108);
+      shouldBeEqualToNumber("entries[2].intersectionRect.top", 508);
+      shouldBeEqualToNumber("entries[2].intersectionRect.bottom", 600);
+      shouldBeEqualToNumber("entries[2].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[2].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[2].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[2].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[2].target", target);
+      document.scrollingElement.scrollTop = 240;
+      requestAnimationFrame(step4);
+    });
   }
-  document.scrollingElement.scrollTop = 740;
-  requestAnimationFrame(step5);
-}
 
-function step5() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 5);
-  if (entries.length > 4) {
-    shouldBeEqualToNumber("entries[4].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[4].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[4].boundingClientRect.top", -32);
-    shouldBeEqualToNumber("entries[4].boundingClientRect.bottom", 68);
-    shouldBeEqualToNumber("entries[4].intersectionRect.left", 8);
-    shouldBeEqualToNumber("entries[4].intersectionRect.right", 108);
-    shouldBeEqualToNumber("entries[4].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[4].intersectionRect.bottom", 68);
-    shouldBeEqualToNumber("entries[4].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[4].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[4].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[4].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[4].target", target);
+  function step4() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 4);
+      shouldBeEqualToNumber("entries[3].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[3].boundingClientRect.right", 108);
+      shouldBeEqualToNumber("entries[3].boundingClientRect.top", 468);
+      shouldBeEqualToNumber("entries[3].boundingClientRect.bottom", 568);
+      shouldBeEqualToNumber("entries[3].intersectionRect.left", 8);
+      shouldBeEqualToNumber("entries[3].intersectionRect.right", 108);
+      shouldBeEqualToNumber("entries[3].intersectionRect.top", 468);
+      shouldBeEqualToNumber("entries[3].intersectionRect.bottom", 568);
+      shouldBeEqualToNumber("entries[3].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[3].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[3].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[3].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[3].target", target);
+      document.scrollingElement.scrollTop = 740;
+      requestAnimationFrame(step5);
+    });
   }
-  document.scrollingElement.scrollTop = 760;
-  requestAnimationFrame(step6);
-}
 
-function step6() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 6);
-  if (entries.length > 5) {
-    shouldBeEqualToNumber("entries[5].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[5].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[5].boundingClientRect.top", -52);
-    shouldBeEqualToNumber("entries[5].boundingClientRect.bottom", 48);
-    shouldBeEqualToNumber("entries[5].intersectionRect.left", 8);
-    shouldBeEqualToNumber("entries[5].intersectionRect.right", 108);
-    shouldBeEqualToNumber("entries[5].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[5].intersectionRect.bottom", 48);
-    shouldBeEqualToNumber("entries[5].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[5].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[5].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[5].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[5].target", target);
+  function step5() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 5);
+      shouldBeEqualToNumber("entries[4].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[4].boundingClientRect.right", 108);
+      shouldBeEqualToNumber("entries[4].boundingClientRect.top", -32);
+      shouldBeEqualToNumber("entries[4].boundingClientRect.bottom", 68);
+      shouldBeEqualToNumber("entries[4].intersectionRect.left", 8);
+      shouldBeEqualToNumber("entries[4].intersectionRect.right", 108);
+      shouldBeEqualToNumber("entries[4].intersectionRect.top", 0);
+      shouldBeEqualToNumber("entries[4].intersectionRect.bottom", 68);
+      shouldBeEqualToNumber("entries[4].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[4].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[4].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[4].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[4].target", target);
+      document.scrollingElement.scrollTop = 760;
+      requestAnimationFrame(step6);
+    });
   }
-  document.scrollingElement.scrollTop = 800;
-  requestAnimationFrame(step7);
-}
 
-function step7() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 7);
-  if (entries.length > 6) {
-    shouldBeEqualToNumber("entries[6].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[6].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[6].boundingClientRect.top", -92);
-    shouldBeEqualToNumber("entries[6].boundingClientRect.bottom", 8);
-    shouldBeEqualToNumber("entries[6].intersectionRect.left", 8);
-    shouldBeEqualToNumber("entries[6].intersectionRect.right", 108);
-    shouldBeEqualToNumber("entries[6].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[6].intersectionRect.bottom", 8);
-    shouldBeEqualToNumber("entries[6].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[6].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[6].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[6].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[6].target", target);
+  function step6() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 6);
+      shouldBeEqualToNumber("entries[5].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[5].boundingClientRect.right", 108);
+      shouldBeEqualToNumber("entries[5].boundingClientRect.top", -52);
+      shouldBeEqualToNumber("entries[5].boundingClientRect.bottom", 48);
+      shouldBeEqualToNumber("entries[5].intersectionRect.left", 8);
+      shouldBeEqualToNumber("entries[5].intersectionRect.right", 108);
+      shouldBeEqualToNumber("entries[5].intersectionRect.top", 0);
+      shouldBeEqualToNumber("entries[5].intersectionRect.bottom", 48);
+      shouldBeEqualToNumber("entries[5].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[5].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[5].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[5].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[5].target", target);
+      document.scrollingElement.scrollTop = 800;
+      requestAnimationFrame(step7);
+    });
   }
-  document.scrollingElement.scrollTop = 820;
-  requestAnimationFrame(step8);
-}
 
-function step8() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 8);
-  if (entries.length > 7) {
-    shouldBeEqualToNumber("entries[7].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[7].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[7].boundingClientRect.top", -112);
-    shouldBeEqualToNumber("entries[7].boundingClientRect.bottom", -12);
-    shouldBeEqualToNumber("entries[7].intersectionRect.left", 0);
-    shouldBeEqualToNumber("entries[7].intersectionRect.right", 0);
-    shouldBeEqualToNumber("entries[7].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[7].intersectionRect.bottom", 0);
-    shouldBeEqualToNumber("entries[7].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[7].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[7].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[7].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[7].target", target);
+  function step7() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 7);
+      shouldBeEqualToNumber("entries[6].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[6].boundingClientRect.right", 108);
+      shouldBeEqualToNumber("entries[6].boundingClientRect.top", -92);
+      shouldBeEqualToNumber("entries[6].boundingClientRect.bottom", 8);
+      shouldBeEqualToNumber("entries[6].intersectionRect.left", 8);
+      shouldBeEqualToNumber("entries[6].intersectionRect.right", 108);
+      shouldBeEqualToNumber("entries[6].intersectionRect.top", 0);
+      shouldBeEqualToNumber("entries[6].intersectionRect.bottom", 8);
+      shouldBeEqualToNumber("entries[6].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[6].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[6].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[6].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[6].target", target);
+      document.scrollingElement.scrollTop = 820;
+      requestAnimationFrame(step8);
+    });
   }
-  finishJSTest();
-  document.scrollingElement.scrollTop = 0;
-}
+
+  function step8() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 8);
+      shouldBeEqualToNumber("entries[7].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[7].boundingClientRect.right", 108);
+      shouldBeEqualToNumber("entries[7].boundingClientRect.top", -112);
+      shouldBeEqualToNumber("entries[7].boundingClientRect.bottom", -12);
+      shouldBeEqualToNumber("entries[7].intersectionRect.left", 0);
+      shouldBeEqualToNumber("entries[7].intersectionRect.right", 0);
+      shouldBeEqualToNumber("entries[7].intersectionRect.top", 0);
+      shouldBeEqualToNumber("entries[7].intersectionRect.bottom", 0);
+      shouldBeEqualToNumber("entries[7].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[7].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[7].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[7].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[7].target", target);
+      finishJSTest();
+      document.scrollingElement.scrollTop = 0;
+    });
+  }
+
+  step0();
 </script>
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/observer-without-js-reference.html b/third_party/WebKit/LayoutTests/intersection-observer/observer-without-js-reference.html
index b4fbd3b..637a955f3 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/observer-without-js-reference.html
+++ b/third_party/WebKit/LayoutTests/intersection-observer/observer-without-js-reference.html
@@ -6,26 +6,19 @@
 <div style="width:100%; height:700px;"></div>
 
 <script>
-jsTestIsAsync = true;
-description("IntersectionObserver continues to produce notifications when it has no javascript references.");
-var target = document.getElementById("target");
-var entries = [];
-new IntersectionObserver(function(changes) {
-    entries.push(...changes);
-}).observe(target);
-gc();
-document.scrollingElement.scrollTop = 300;
-// See README for explanation of double RAF.
-requestAnimationFrame(() => { requestAnimationFrame(() => {
-  // In other IntersectionObserver tests, observer.takeRecords() is used to ensure that
-  // all pending notifications are taken.  Because this test specifically tests the
-  // case where the observer object has no js references, it can't use takeRecords().
-  // However, the IntersectionObserver spec mandates that all notifications must be
-  // sent within 100ms of being generated, so this timeout effectively tests conformance
-  // with that requirement.
-  setTimeout(() => {
-    shouldBeEqualToNumber("entries.length", 1);
-    finishJSTest();
-  }, 100)
-}) });
+  jsTestIsAsync = true;
+  description("IntersectionObserver continues to produce notifications when it has no javascript references.");
+  var target = document.getElementById("target");
+  var entries = [];
+  new IntersectionObserver(function(changes) {
+      entries.push(...changes);
+  }).observe(target);
+  gc();
+  document.scrollingElement.scrollTop = 300;
+  requestAnimationFrame(function () {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 1);
+      finishJSTest();
+    });
+  });
 </script>
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/root-margin-expected.txt b/third_party/WebKit/LayoutTests/intersection-observer/root-margin-expected.txt
index a88ff82..910c278 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/root-margin-expected.txt
+++ b/third_party/WebKit/LayoutTests/intersection-observer/root-margin-expected.txt
@@ -3,13 +3,11 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS new IntersectionObserver(c => {}, { rootMargin: '1.4px' }) did not throw exception.
-PASS new IntersectionObserver(c => {}, { rootMargin: '1.4px 2px' }) did not throw exception.
-PASS new IntersectionObserver(c => {}, { rootMargin: '1.4px 2px 3%' }) did not throw exception.
-PASS new IntersectionObserver(c => {}, { rootMargin: '1.4px 2px 3% 40px junk junk junk' }) did not throw exception.
+PASS new IntersectionObserver(observer_callback, { rootMargin: '1.4px' }) did not throw exception.
+PASS new IntersectionObserver(observer_callback, { rootMargin: '1.4px 2px' }) did not throw exception.
+PASS new IntersectionObserver(observer_callback, { rootMargin: '1.4px 2px 3%' }) did not throw exception.
+PASS new IntersectionObserver(observer_callback, { rootMargin: '1.4px 2px 3% 40px junk junk junk' }) did not throw exception.
 PASS entries.length is 0
-PASS entries.length is 0
-PASS entries.length is 1
 PASS entries.length is 1
 PASS entries[0].boundingClientRect.left is 912
 PASS entries[0].boundingClientRect.right is 1012
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/root-margin.html b/third_party/WebKit/LayoutTests/intersection-observer/root-margin.html
index dda62ea3..c5dd9433 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/root-margin.html
+++ b/third_party/WebKit/LayoutTests/intersection-observer/root-margin.html
@@ -10,84 +10,83 @@
 <div style="width:100%; height:700px;"></div>
 
 <script>
-description("Intersection observer test with root margin and implicit root.");
-var target = document.getElementById("target");
-var entries = [];
-var observer = new IntersectionObserver(
-    changes => { entries = entries.concat(changes) },
-    { rootMargin: "10px 20% 40% 30px" }
-);
+  description("Intersection observer test with root margin and implicit root.");
+  var target = document.getElementById("target");
+  var entries = [];
 
-shouldNotThrow("new IntersectionObserver(c => {}, { rootMargin: '1.4px' })");
-shouldNotThrow("new IntersectionObserver(c => {}, { rootMargin: '1.4px 2px' })");
-shouldNotThrow("new IntersectionObserver(c => {}, { rootMargin: '1.4px 2px 3%' })");
-shouldNotThrow("new IntersectionObserver(c => {}, { rootMargin: '1.4px 2px 3% 40px junk junk junk' })");
+  function observer_callback(changes) {
+    for (var i in changes)
+      entries.push(changes[i]);
+  }
 
-onload = function() {
+  var observer = new IntersectionObserver(observer_callback, {
+    rootMargin: "10px 20% 40% 30px"
+  });
   observer.observe(target);
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  // See README for explanation of double RAF.
-  requestAnimationFrame(() => { requestAnimationFrame(step0) });
-}
 
-function step0() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  document.scrollingElement.scrollLeft = 100;
-  requestAnimationFrame(step1);
-}
-
-function step1() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 1);
-  if (entries.length > 0) {
-    shouldBeEqualToNumber("entries.length", 1);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.left", 912);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.right", 1012);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.top", 708);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 808);
-    shouldBeEqualToNumber("entries[0].intersectionRect.left", 912);
-    shouldBeEqualToNumber("entries[0].intersectionRect.right", 942);
-    shouldBeEqualToNumber("entries[0].intersectionRect.top", 708);
-    shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 808);
-    shouldBeEqualToNumber("entries[0].rootBounds.left", -30);
-    shouldBeEqualToNumber("entries[0].rootBounds.right", 942);
-    shouldBeEqualToNumber("entries[0].rootBounds.top", -10);
-    shouldBeEqualToNumber("entries[0].rootBounds.bottom", 819);
-    shouldEvaluateToSameObject("entries[0].target", target);
+  function step0() {
+    setTimeout(function() {
+      shouldNotThrow("new IntersectionObserver(observer_callback, { rootMargin: '1.4px' })");
+      shouldNotThrow("new IntersectionObserver(observer_callback, { rootMargin: '1.4px 2px' })");
+      shouldNotThrow("new IntersectionObserver(observer_callback, { rootMargin: '1.4px 2px 3%' })");
+      shouldNotThrow("new IntersectionObserver(observer_callback, { rootMargin: '1.4px 2px 3% 40px junk junk junk' })");
+      shouldBeEqualToNumber("entries.length", 0);
+      document.scrollingElement.scrollLeft = 100;
+      requestAnimationFrame(step1);
+    });
   }
-  document.scrollingElement.scrollTop = 800;
-  requestAnimationFrame(step2);
-}
 
-function step2() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 1);
-  document.scrollingElement.scrollTop = 900;
-  requestAnimationFrame(step3);
-}
-
-function step3() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 2);
-  if (entries.length > 1) {
-    shouldBeEqualToNumber("entries[1].boundingClientRect.left", 912);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.right", 1012);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.top", -192);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", -92);
-    shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.left", -30);
-    shouldBeEqualToNumber("entries[1].rootBounds.right", 942);
-    shouldBeEqualToNumber("entries[1].rootBounds.top", -10);
-    shouldBeEqualToNumber("entries[1].rootBounds.bottom", 819);
-    shouldEvaluateToSameObject("entries[1].target", target);
+  function step1() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 1);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.left", 912);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.right", 1012);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.top", 708);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 808);
+      shouldBeEqualToNumber("entries[0].intersectionRect.left", 912);
+      shouldBeEqualToNumber("entries[0].intersectionRect.right", 942);
+      shouldBeEqualToNumber("entries[0].intersectionRect.top", 708);
+      shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 808);
+      shouldBeEqualToNumber("entries[0].rootBounds.left", -30);
+      shouldBeEqualToNumber("entries[0].rootBounds.right", 942);
+      shouldBeEqualToNumber("entries[0].rootBounds.top", -10);
+      shouldBeEqualToNumber("entries[0].rootBounds.bottom", 819);
+      shouldEvaluateToSameObject("entries[0].target", target);
+      document.scrollingElement.scrollTop = 800;
+      requestAnimationFrame(step2);
+    });
   }
-  finishJSTest();
-  document.scrollingElement.scrollLeft = 0;
-  document.scrollingElement.scrollTop = 0;
-}
+
+  function step2() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 1);
+      document.scrollingElement.scrollTop = 900;
+      requestAnimationFrame(step3);
+    });
+  }
+
+  function step3() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 2);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.left", 912);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.right", 1012);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.top", -192);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", -92);
+      shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.left", -30);
+      shouldBeEqualToNumber("entries[1].rootBounds.right", 942);
+      shouldBeEqualToNumber("entries[1].rootBounds.top", -10);
+      shouldBeEqualToNumber("entries[1].rootBounds.bottom", 819);
+      shouldEvaluateToSameObject("entries[1].target", target);
+
+      finishJSTest();
+      document.scrollingElement.scrollLeft = 0;
+      document.scrollingElement.scrollTop = 0;
+    });
+  }
+
+  step0();
 </script>
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/same-document-no-root.html b/third_party/WebKit/LayoutTests/intersection-observer/same-document-no-root.html
index 5d8a01b8..168a2cf 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/same-document-no-root.html
+++ b/third_party/WebKit/LayoutTests/intersection-observer/same-document-no-root.html
@@ -6,67 +6,68 @@
 <div style="width:100%; height:700px;"></div>
 
 <script>
-description("Simple intersection observer test with no explicit root and one document.");
-var target = document.getElementById("target");
-var entries = [];
-var observer = new IntersectionObserver(changes => { entries = entries.concat(changes) });
-
-onload = function() {
+  description("Simple intersection observer test with no explicit root and one document.");
+  var target = document.getElementById("target");
+  var entries = [];
+  observer_callback = function(changes) {
+    for (var i in changes)
+      entries.push(changes[i]);
+  };
+  var observer = new IntersectionObserver(observer_callback, {});
   observer.observe(target);
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  document.scrollingElement.scrollTop = 300;
-  // See README for explanation of double RAF.
-  requestAnimationFrame(() => { requestAnimationFrame(step1) });
-};
 
-function step1() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 1);
-  if (entries.length > 0) {
-    shouldBeEqualToNumber("entries[0].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.top", 408);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 508);
-    shouldBeEqualToNumber("entries[0].intersectionRect.left", 8);
-    shouldBeEqualToNumber("entries[0].intersectionRect.right", 108);
-    shouldBeEqualToNumber("entries[0].intersectionRect.top", 408);
-    shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 508);
-    shouldBeEqualToNumber("entries[0].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[0].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[0].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[0].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[0].target", target);
+  onload = function() {
+    shouldBeEqualToNumber("entries.length", 0);
+    document.scrollingElement.scrollTop = 300;
+    requestAnimationFrame(step1);
+  };
 
-    // ClientRect members of IntersectionObserverEntry should be stable.
-    shouldEvaluateToSameObject("entries[0].boundingClientRect", entries[0].boundingClientRect);
-    shouldEvaluateToSameObject("entries[0].intersectionRect", entries[0].intersectionRect);
-    shouldEvaluateToSameObject("entries[0].rootBounds", entries[0].rootBounds);
+  function step1() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 1);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.right", 108);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.top", 408);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 508);
+      shouldBeEqualToNumber("entries[0].intersectionRect.left", 8);
+      shouldBeEqualToNumber("entries[0].intersectionRect.right", 108);
+      shouldBeEqualToNumber("entries[0].intersectionRect.top", 408);
+      shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 508);
+      shouldBeEqualToNumber("entries[0].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[0].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[0].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[0].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[0].target", target);
+
+      // ClientRect members of IntersectionObserverEntry should be stable.
+      shouldEvaluateToSameObject("entries[0].boundingClientRect", entries[0].boundingClientRect);
+      shouldEvaluateToSameObject("entries[0].intersectionRect", entries[0].intersectionRect);
+      shouldEvaluateToSameObject("entries[0].rootBounds", entries[0].rootBounds);
+
+      document.scrollingElement.scrollTop = 100;
+      requestAnimationFrame(step2);
+    });
   }
-  document.scrollingElement.scrollTop = 100;
-  requestAnimationFrame(step2);
-}
 
-function step2() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 2);
-  if (entries.length > 1) {
-    shouldBeEqualToNumber("entries[1].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.right", 108);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.top", 608);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 708);
-    shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[1].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[1].target", target);
+  function step2() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 2);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.right", 108);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.top", 608);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 708);
+      shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[1].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[1].target", target);
+      finishJSTest();
+      document.scrollingElement.scrollTop = 0;
+    });
   }
-  finishJSTest();
-  document.scrollingElement.scrollTop = 0;
-}
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/same-document-root-expected.txt b/third_party/WebKit/LayoutTests/intersection-observer/same-document-root-expected.txt
index af7109b2..157d6e5e 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/same-document-root-expected.txt
+++ b/third_party/WebKit/LayoutTests/intersection-observer/same-document-root-expected.txt
@@ -5,7 +5,6 @@
 
 PASS entries.length is 0
 PASS entries.length is 0
-PASS entries.length is 0
 PASS entries.length is 1
 PASS entries[0].boundingClientRect.left is 11
 PASS entries[0].boundingClientRect.right is 111
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/same-document-root.html b/third_party/WebKit/LayoutTests/intersection-observer/same-document-root.html
index 05a808b..d96f6d1 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/same-document-root.html
+++ b/third_party/WebKit/LayoutTests/intersection-observer/same-document-root.html
@@ -9,107 +9,105 @@
 <div style="width:100%;height:700px;"></div>
 
 <script>
-description("Simple intersection observer test with explicit root and target in the same document.");
-var target = document.getElementById("target");
-var root = document.getElementById("root");
-var entries = [];
-var observer = new IntersectionObserver(
-    changes => { entries = entries.concat(changes) },
-    { root: document.getElementById("root") }
-);
+  description("Simple intersection observer test with explicit root and target in the same document.");
+  var target = document.getElementById("target");
+  var root = document.getElementById("root");
+  var entries = [];
 
-onload = function() {
+  observer_callback = function(changes) {
+    for (var i in changes)
+      entries.push(changes[i]);
+  };
+  var observer = new IntersectionObserver(observer_callback, {"root": document.getElementById("root")});
   observer.observe(target);
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  requestAnimationFrame(() => { requestAnimationFrame(step0) });
-}
 
-// Test that notifications are not generated when the target is overflow clipped by the root.
-function step0() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  document.scrollingElement.scrollTop = 600;
-  requestAnimationFrame(step1);
-}
-
-function step1() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  root.scrollTop = 150;
-  requestAnimationFrame(step2);
-}
-
-function step2() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 1);
-  if (entries.length > 0) {
-    shouldBeEqualToNumber("entries[0].boundingClientRect.left", 11);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.right", 111);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.top", 261);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 361);
-    shouldBeEqualToNumber("entries[0].intersectionRect.left", 11);
-    shouldBeEqualToNumber("entries[0].intersectionRect.right", 111);
-    shouldBeEqualToNumber("entries[0].intersectionRect.top", 261);
-    shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 311);
-    shouldBeEqualToNumber("entries[0].rootBounds.left", 11);
-    shouldBeEqualToNumber("entries[0].rootBounds.right", 111);
-    shouldBeEqualToNumber("entries[0].rootBounds.top", 111);
-    shouldBeEqualToNumber("entries[0].rootBounds.bottom", 311);
-    shouldEvaluateToSameObject("entries[0].target", target);
+  // Test that notifications are not generated when the target is overflow clipped by the root.
+  function step0() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 0);
+      document.scrollingElement.scrollTop = 600;
+      requestAnimationFrame(step1);
+    });
   }
-  document.scrollingElement.scrollTop = 0;
-  requestAnimationFrame(step3);
-}
 
-function step3() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 1);
-  root.scrollTop = 0;
-  requestAnimationFrame(step4);
-}
-
-function step4() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 2);
-  if (entries.length > 1) {
-    shouldBeEqualToNumber("entries[1].boundingClientRect.left", 11);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.right", 111);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.top", 1011);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 1111);
-    shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.left", 11);
-    shouldBeEqualToNumber("entries[1].rootBounds.right", 111);
-    shouldBeEqualToNumber("entries[1].rootBounds.top", 711);
-    shouldBeEqualToNumber("entries[1].rootBounds.bottom", 911);
-    shouldEvaluateToSameObject("entries[1].target", target);
+  function step1() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 0);
+      root.scrollTop = 150;
+      requestAnimationFrame(step2);
+    });
   }
-  root.scrollTop = 150;
-  requestAnimationFrame(step5);
-}
 
-// This tests that notifications are generated even when the root element is off screen.
-function step5() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 3);
-  if (entries.length > 2) {
-    shouldBeEqualToNumber("entries[2].boundingClientRect.left", 11);
-    shouldBeEqualToNumber("entries[2].boundingClientRect.right", 111);
-    shouldBeEqualToNumber("entries[2].boundingClientRect.top", 861);
-    shouldBeEqualToNumber("entries[2].boundingClientRect.bottom", 961);
-    shouldBeEqualToNumber("entries[2].intersectionRect.left", 11);
-    shouldBeEqualToNumber("entries[2].intersectionRect.right", 111);
-    shouldBeEqualToNumber("entries[2].intersectionRect.top", 861);
-    shouldBeEqualToNumber("entries[2].intersectionRect.bottom", 911);
-    shouldBeEqualToNumber("entries[2].rootBounds.left", 11);
-    shouldBeEqualToNumber("entries[2].rootBounds.right", 111);
-    shouldBeEqualToNumber("entries[2].rootBounds.top", 711);
-    shouldBeEqualToNumber("entries[2].rootBounds.bottom", 911);
-    shouldEvaluateToSameObject("entries[2].target", target);
+  function step2() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 1);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.left", 11);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.right", 111);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.top", 261);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 361);
+      shouldBeEqualToNumber("entries[0].intersectionRect.left", 11);
+      shouldBeEqualToNumber("entries[0].intersectionRect.right", 111);
+      shouldBeEqualToNumber("entries[0].intersectionRect.top", 261);
+      shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 311);
+      shouldBeEqualToNumber("entries[0].rootBounds.left", 11);
+      shouldBeEqualToNumber("entries[0].rootBounds.right", 111);
+      shouldBeEqualToNumber("entries[0].rootBounds.top", 111);
+      shouldBeEqualToNumber("entries[0].rootBounds.bottom", 311);
+      shouldEvaluateToSameObject("entries[0].target", target);
+      document.scrollingElement.scrollTop = 0;
+      requestAnimationFrame(step3);
+    });
   }
-  finishJSTest();
-}
+
+  function step3() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 1);
+      root.scrollTop = 0;
+      requestAnimationFrame(step4);
+    });
+  }
+
+  function step4() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 2);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.left", 11);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.right", 111);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.top", 1011);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 1111);
+      shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.left", 11);
+      shouldBeEqualToNumber("entries[1].rootBounds.right", 111);
+      shouldBeEqualToNumber("entries[1].rootBounds.top", 711);
+      shouldBeEqualToNumber("entries[1].rootBounds.bottom", 911);
+      shouldEvaluateToSameObject("entries[1].target", target);
+      root.scrollTop = 150;
+      requestAnimationFrame(step5);
+    });
+  }
+
+  // This tests that notifications are generated even when the root element is off screen.
+  function step5() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 3);
+      shouldBeEqualToNumber("entries[2].boundingClientRect.left", 11);
+      shouldBeEqualToNumber("entries[2].boundingClientRect.right", 111);
+      shouldBeEqualToNumber("entries[2].boundingClientRect.top", 861);
+      shouldBeEqualToNumber("entries[2].boundingClientRect.bottom", 961);
+      shouldBeEqualToNumber("entries[2].intersectionRect.left", 11);
+      shouldBeEqualToNumber("entries[2].intersectionRect.right", 111);
+      shouldBeEqualToNumber("entries[2].intersectionRect.top", 861);
+      shouldBeEqualToNumber("entries[2].intersectionRect.bottom", 911);
+      shouldBeEqualToNumber("entries[2].rootBounds.left", 11);
+      shouldBeEqualToNumber("entries[2].rootBounds.right", 111);
+      shouldBeEqualToNumber("entries[2].rootBounds.top", 711);
+      shouldBeEqualToNumber("entries[2].rootBounds.bottom", 911);
+      shouldEvaluateToSameObject("entries[2].target", target);
+      finishJSTest();
+    });
+  }
+
+  step0();
 </script>
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/same-document-zero-size-target.html b/third_party/WebKit/LayoutTests/intersection-observer/same-document-zero-size-target.html
index d29df90..4a5b435 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/same-document-zero-size-target.html
+++ b/third_party/WebKit/LayoutTests/intersection-observer/same-document-zero-size-target.html
@@ -6,66 +6,68 @@
 <div style="width:100%; height:700px;"></div>
 
 <script>
-description("Iintersection observer test with zero-size target element.");
-var target = document.getElementById("target");
-var entries = [];
-var observer = new IntersectionObserver(changes => { entries = entries.concat(changes) }, {});
-
-onload = function() {
+  description("Iintersection observer test with zero-size target element.");
+  var target = document.getElementById("target");
+  var entries = [];
+  observer_callback = function(changes) {
+    for (var i in changes)
+      entries.push(changes[i]);
+  };
+  var observer = new IntersectionObserver(observer_callback, {});
   observer.observe(target);
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 0);
-  document.scrollingElement.scrollTop = 300;
-  // See README for explanation of double RAF.
-  requestAnimationFrame(() => { requestAnimationFrame(step1) });
-};
 
-function step1() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 1);
-  if (entries.length > 0) {
-    shouldBeEqualToNumber("entries[0].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.right", 9);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.top", 408);
-    shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 409);
-    shouldBeEqualToNumber("entries[0].intersectionRect.left", 8);
-    shouldBeEqualToNumber("entries[0].intersectionRect.right", 9);
-    shouldBeEqualToNumber("entries[0].intersectionRect.top", 408);
-    shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 409);
-    shouldBeEqualToNumber("entries[0].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[0].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[0].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[0].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[0].target", target);
+  onload = function() {
+    shouldBeEqualToNumber("entries.length", 0);
+    document.scrollingElement.scrollTop = 300;
+    requestAnimationFrame(step1);
+  };
 
-    // ClientRect members of IntersectionObserverEntry should be stable.
-    shouldEvaluateToSameObject("entries[0].boundingClientRect", entries[0].boundingClientRect);
-    shouldEvaluateToSameObject("entries[0].intersectionRect", entries[0].intersectionRect);
-    shouldEvaluateToSameObject("entries[0].rootBounds", entries[0].rootBounds);
+  function step1() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 1);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.right", 9);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.top", 408);
+      shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 409);
+      shouldBeEqualToNumber("entries[0].intersectionRect.left", 8);
+      shouldBeEqualToNumber("entries[0].intersectionRect.right", 9);
+      shouldBeEqualToNumber("entries[0].intersectionRect.top", 408);
+      shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 409);
+      shouldBeEqualToNumber("entries[0].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[0].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[0].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[0].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[0].target", target);
+
+      // ClientRect members of IntersectionObserverEntry should be stable.
+      shouldEvaluateToSameObject("entries[0].boundingClientRect", entries[0].boundingClientRect);
+      shouldEvaluateToSameObject("entries[0].intersectionRect", entries[0].intersectionRect);
+      shouldEvaluateToSameObject("entries[0].rootBounds", entries[0].rootBounds);
+
+      document.scrollingElement.scrollTop = 100;
+      requestAnimationFrame(step2);
+    });
   }
-  document.scrollingElement.scrollTop = 100;
-  requestAnimationFrame(step2);
-}
 
-function step2() {
-  entries = entries.concat(observer.takeRecords());
-  shouldBeEqualToNumber("entries.length", 2);
-  if (entries.length > 1) {
-    shouldBeEqualToNumber("entries[1].boundingClientRect.left", 8);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.right", 9);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.top", 608);
-    shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 609);
-    shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
-    shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.left", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.right", 785);
-    shouldBeEqualToNumber("entries[1].rootBounds.top", 0);
-    shouldBeEqualToNumber("entries[1].rootBounds.bottom", 600);
-    shouldEvaluateToSameObject("entries[1].target", target);
+  function step2() {
+    setTimeout(function() {
+      shouldBeEqualToNumber("entries.length", 2);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.left", 8);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.right", 9);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.top", 608);
+      shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 609);
+      shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
+      shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.left", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.right", 785);
+      shouldBeEqualToNumber("entries[1].rootBounds.top", 0);
+      shouldBeEqualToNumber("entries[1].rootBounds.bottom", 600);
+      shouldEvaluateToSameObject("entries[1].target", target);
+      finishJSTest();
+      document.scrollingElement.scrollTop = 0;
+    });
   }
-  finishJSTest();
-  document.scrollingElement.scrollTop = 0;
-}
+
 </script>
diff --git a/third_party/WebKit/LayoutTests/intersection-observer/timestamp.html b/third_party/WebKit/LayoutTests/intersection-observer/timestamp.html
index fa967660..47f1dcc 100644
--- a/third_party/WebKit/LayoutTests/intersection-observer/timestamp.html
+++ b/third_party/WebKit/LayoutTests/intersection-observer/timestamp.html
@@ -8,8 +8,6 @@
 description("Test that intersection observer time is relative to time in the callback context.");
 var topWindowEntries = [];
 var iframeWindowEntries = [];
-var topWindowObserver;
-var iframeWindowObserver;
 var targetIframe;
 var iframeScroller;
 var topWindowTime;
@@ -17,36 +15,36 @@
 var timestampTolerance = 24;  // 1.5 times frame duration.
 
 function step0() {
-  // Test results are only significant if there's a sufficient gap between
-  // top window time and iframe window time.
-  topWindowTime = performance.now();
-  iframeWindowTime = targetIframe.contentWindow.performance.now();
-  shouldBeGreaterThan("topWindowTime - iframeWindowTime", "2 * timestampTolerance");
+  setTimeout(function() {
+    // Test results are only significant if there's a sufficient gap between
+    // top window time and iframe window time.
+    topWindowTime = performance.now();
+    iframeWindowTime = targetIframe.contentWindow.performance.now();
+    shouldBeGreaterThan("topWindowTime - iframeWindowTime", "2 * timestampTolerance");
 
-  topWindowEntries = topWindowEntries.concat(topWindowObserver.takeRecords());
-  iframeWindowEntries = iframeWindowEntries.concat(iframeWindowObserver.takeRecords());
-  shouldBeEqualToNumber("topWindowEntries.length", 0);
-  shouldBeEqualToNumber("iframeWindowEntries.length", 0);
-  document.scrollingElement.scrollTop = 200;
-  iframeScroller.scrollTop = 250;
-  requestAnimationFrame(step1);
+    shouldBeEqualToNumber("topWindowEntries.length", 0);
+    shouldBeEqualToNumber("iframeWindowEntries.length", 0);
+    document.scrollingElement.scrollTop = 200;
+    iframeScroller.scrollTop = 250;
+    requestAnimationFrame(step1);
+  });
 }
 
 function step1() {
-  topWindowEntries = topWindowEntries.concat(topWindowObserver.takeRecords());
-  iframeWindowEntries = iframeWindowEntries.concat(iframeWindowObserver.takeRecords());
-  topWindowTime = performance.now();
-  iframeWindowTime = targetIframe.contentWindow.performance.now();
-  shouldBeEqualToNumber("topWindowEntries.length", 1);
-  if (topWindowEntries.length) {
-    shouldBeCloseTo("topWindowEntries[0].time", "topWindowTime", timestampTolerance);
-  }
-  shouldBeEqualToNumber("iframeWindowEntries.length", 1);
-  if (iframeWindowEntries.length) {
-    shouldBeCloseTo("iframeWindowEntries[0].time", "iframeWindowTime", timestampTolerance);
-  }
-  finishJSTest();
-  document.scrollingElement.scrollTop = 0;
+  setTimeout(function() {
+    topWindowTime = performance.now();
+    iframeWindowTime = targetIframe.contentWindow.performance.now();
+    shouldBeEqualToNumber("topWindowEntries.length", 1);
+    if (topWindowEntries.length) {
+      shouldBeCloseTo("topWindowEntries[0].time", "topWindowTime", timestampTolerance);
+    }
+    shouldBeEqualToNumber("iframeWindowEntries.length", 1);
+    if (iframeWindowEntries.length) {
+      shouldBeCloseTo("iframeWindowEntries[0].time", "iframeWindowTime", timestampTolerance);
+    }
+    finishJSTest();
+    document.scrollingElement.scrollTop = 0;
+  });
 }
 
 function runTest() {
@@ -55,19 +53,18 @@
 
   // Observer created here, callback created in iframe context.  Timestamps should be
   // from this window.
-  topWindowObserver = new IntersectionObserver(targetIframe.contentDocument.createObserverCallback(topWindowEntries), {});
-  topWindowObserver.observe(target);
+  var observer = new IntersectionObserver(targetIframe.contentDocument.createObserverCallback(topWindowEntries), {});
+  observer.observe(target);
 
   // Callback created here, observer created in iframe.  Timestamps should be
   // from iframe window.
-  iframeWindowObserver = targetIframe.contentDocument.createObserver(function(newEntries) {
+  observer = targetIframe.contentDocument.createObserver(function(newEntries) {
     for (var i = 0; i < newEntries.length; i++)
       iframeWindowEntries.push(newEntries[i]);
   });
-  iframeWindowObserver.observe(target);
+  observer.observe(target);
 
-  // See README for explanation of double RAF.
-  requestAnimationFrame(() => { requestAnimationFrame(step0) });
+  step0();
 }
 
 window.onload = function() {
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/scrollbars/listbox-scrollbar-combinations-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/scrollbars/listbox-scrollbar-combinations-expected.txt
index 27d6abd..6d3101e6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/scrollbars/listbox-scrollbar-combinations-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/scrollbars/listbox-scrollbar-combinations-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: Elements using the 'border-image' CSS property with no 'border-style' set should have no border, but currently do. Setting 'border-style' will be required in M51, around May 2016. See https://www.chromestatus.com/features/5542503914668032 for more details.
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/inserting/4960120-1-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/editing/inserting/4960120-1-expected.txt
index 6ed6b1f..0ab9438 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/inserting/4960120-1-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/inserting/4960120-1-expected.txt
@@ -14,6 +14,5 @@
     LayoutBlockFlow {DIV} at (3,3) size 135x26
       LayoutText {#text} at (0,0) size 0x13
         text run at (0,0) width 0: " "
-      LayoutText {#text} at (0,13) size 0x13
-        text run at (0,13) width 0: " "
-caret: position 0 of child 1 {#text} of child 0 {DIV} of {#document-fragment} of child 2 {TEXTAREA} of body
+      LayoutBR {BR} at (0,13) size 0x13
+caret: position 0 of child 1 {BR} of child 0 {DIV} of {#document-fragment} of child 2 {TEXTAREA} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/execCommand/indent-pre-expected.txt b/third_party/WebKit/LayoutTests/platform/win/editing/execCommand/indent-pre-expected.txt
index ff09c29..1a6ba66 100644
--- a/third_party/WebKit/LayoutTests/platform/win/editing/execCommand/indent-pre-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/editing/execCommand/indent-pre-expected.txt
@@ -104,7 +104,7 @@
     var textNode = node.firstChild;
     if (textNode.nodeType != Node.TEXT_NODE)
         throw "Wrong node type: " + textNode;
-    execSetSelectionCommand(textNode, 0, 0);
+    execSetSelectionCommand(textNode, 0, textNode, 0);
 }
 
 function verifyTextSelection(startNode, startOffset, endNode, endOffset)
@@ -161,7 +161,7 @@
 execMoveSelectionForwardByLineCommand();
 execExtendSelectionForwardByLineCommand();
 execExtendSelectionForwardByLineCommand();
-// FIXME: This is wrong.  The pre tags get copied when they shouldn't be. 
+// FIXME: This is wrong.  The pre tags get copied when they shouldn't be.
 // See https://bugs.webkit.org/show_bug.cgi?id=42009
 document.execCommand("indent");
 document.getElementById("results").innerText = "PASSED (did not crash)";
diff --git a/third_party/WebKit/LayoutTests/svg/text/text-layout-crash.html b/third_party/WebKit/LayoutTests/svg/text/text-layout-crash.html
index fdf9577..1ee95f04 100644
--- a/third_party/WebKit/LayoutTests/svg/text/text-layout-crash.html
+++ b/third_party/WebKit/LayoutTests/svg/text/text-layout-crash.html
@@ -10,7 +10,7 @@
     document.body.style.zoom=0.9;
 
     document.designMode='on';
-    window.getSelection().setBaseAndExtent(filterInFirstRoot, 0, 5);
+    window.getSelection().setBaseAndExtent(filterInFirstRoot, 0, null, 0);
     document.execCommand('ForwardDelete');
   }
 </script>
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
index 0f42754..8fc5b89 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
@@ -192,6 +192,7 @@
     property removeEventListener
     property replaceChild
     property requestPointerLock
+    property rootNode
     property scrollHeight
     property scrollIntoView
     property scrollIntoViewIfNeeded
@@ -1236,6 +1237,7 @@
     property removeEventListener
     property replaceChild
     property requestPointerLock
+    property rootNode
     property scrollHeight
     property scrollIntoView
     property scrollIntoViewIfNeeded
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
index 7ba1b95..efc9f94 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -3122,6 +3122,7 @@
     getter parentElement
     getter parentNode
     getter previousSibling
+    getter rootNode
     getter textContent
     method appendChild
     method cloneNode
diff --git a/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
index ba889fe..3a68a79 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
@@ -12,7 +12,6 @@
 #include "bindings/core/v8/V8BindingForTesting.h"
 #include "bindings/core/v8/V8BindingMacros.h"
 #include "bindings/core/v8/V8IteratorResultValue.h"
-#include "bindings/core/v8/V8RecursionScope.h"
 #include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/Document.h"
 #include "core/streams/ReadableStreamController.h"
@@ -139,7 +138,7 @@
     ~ReadableStreamOperationsTest() override
     {
         // Execute all pending microtasks
-        v8::MicrotasksScope::PerformCheckpoint(isolate());
+        isolate()->RunMicrotasks();
         EXPECT_FALSE(m_block.HasCaught());
     }
 
@@ -150,7 +149,6 @@
     {
         v8::Local<v8::String> source;
         v8::Local<v8::Script> script;
-        V8RecursionScope::MicrotaskSuppression microtasks(isolate());
         if (!v8Call(v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNormal), source)) {
             ADD_FAILURE();
             return ScriptValue();
@@ -255,12 +253,12 @@
         Function::createFunction(getScriptState(), it2),
         NotReached::createFunction(getScriptState()));
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_FALSE(it1->isSet());
     EXPECT_FALSE(it2->isSet());
 
     ASSERT_FALSE(evalWithPrintingError("controller.enqueue('hello')").isEmpty());
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_TRUE(it1->isSet());
     EXPECT_TRUE(it1->isValid());
     EXPECT_FALSE(it1->isDone());
@@ -268,7 +266,7 @@
     EXPECT_FALSE(it2->isSet());
 
     ASSERT_FALSE(evalWithPrintingError("controller.close()").isEmpty());
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_TRUE(it1->isSet());
     EXPECT_TRUE(it1->isValid());
     EXPECT_FALSE(it1->isDone());
@@ -311,7 +309,7 @@
     ReadableStreamOperations::read(getScriptState(), reader).then(Function::createFunction(getScriptState(), it2), NotReached::createFunction(getScriptState()));
     ReadableStreamOperations::read(getScriptState(), reader).then(Function::createFunction(getScriptState(), it3), NotReached::createFunction(getScriptState()));
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ(10, underlyingSource->desiredSize());
 
@@ -328,7 +326,7 @@
     EXPECT_FALSE(it3->isSet());
 
     underlyingSource->close();
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(it3->isSet());
     EXPECT_TRUE(it3->isValid());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
index 52af5edc..65c9393 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
@@ -281,7 +281,7 @@
     getProperty()->resolve(value);
     EXPECT_EQ(Property::Resolved, getProperty()->getState());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(1u, nOtherResolveCalls);
     EXPECT_EQ(wrap(mainWorld(), value), actual);
@@ -307,7 +307,7 @@
     getProperty()->resolve(value);
     EXPECT_EQ(Property::Resolved, getProperty()->getState());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(0u, nOtherResolveCalls);
 
@@ -316,7 +316,7 @@
         otherPromise.then(stub(currentScriptState(), otherActual, nOtherResolveCalls), notReached(currentScriptState()));
     }
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(1u, nOtherResolveCalls);
     EXPECT_EQ(wrap(mainWorld(), value), actual);
@@ -343,7 +343,7 @@
         getProperty()->promise(otherWorld()).then(notReached(currentScriptState()), stub(currentScriptState(), otherActual, nOtherRejectCalls));
     }
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ(1u, nRejectCalls);
     EXPECT_EQ(wrap(mainWorld(), reason), actual);
     EXPECT_EQ(1u, nOtherRejectCalls);
@@ -374,7 +374,7 @@
     getProperty()->resolve(new GarbageCollectedScriptWrappable("value"));
     EXPECT_EQ(Property::Pending, getProperty()->getState());
 
-    v8::MicrotasksScope::PerformCheckpoint(v8::Isolate::GetCurrent());
+    v8::Isolate::GetCurrent()->RunMicrotasks();
 }
 
 TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reset)
@@ -405,7 +405,7 @@
     EXPECT_EQ(0u, nOldResolveCalls);
     EXPECT_EQ(0u, nNewRejectCalls);
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ(1u, nOldResolveCalls);
     EXPECT_EQ(1u, nNewRejectCalls);
     EXPECT_NE(oldPromise, newPromise);
@@ -445,7 +445,7 @@
     getProperty()->resolve(value.get());
     EXPECT_EQ(Property::Resolved, getProperty()->getState());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(wrap(mainWorld(), value), actual);
 }
@@ -464,7 +464,7 @@
     getProperty()->reject(reason);
     EXPECT_EQ(Property::Rejected, getProperty()->getState());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ(1u, nRejectCalls);
     EXPECT_EQ(wrap(mainWorld(), reason), actual);
 }
@@ -514,7 +514,7 @@
             property->promise(DOMWrapperWorld::mainWorld()).then(stub(currentScriptState(), actualValue, nResolveCalls), notReached(currentScriptState()));
         }
         property->resolve(value);
-        v8::MicrotasksScope::PerformCheckpoint(isolate());
+        isolate()->RunMicrotasks();
         {
             ScriptState::Scope scope(mainScriptState());
             actual = toCoreString(actualValue.v8Value()->ToString(mainScriptState()->context()).ToLocalChecked());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp
index 23f2b2a..ea55caa 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp
@@ -60,7 +60,7 @@
         createClosure(callback, v8::Undefined(isolate()), isolate());
 
         // Execute all pending microtasks
-        v8::MicrotasksScope::PerformCheckpoint(isolate());
+        isolate()->RunMicrotasks();
     }
 
     OwnPtr<DummyPageHolder> m_pageHolder;
@@ -96,7 +96,7 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -111,14 +111,14 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ("hello", onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
     resolver->resolve("bye");
     resolver->reject("bye");
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ("hello", onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -144,7 +144,7 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -159,14 +159,14 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ("hello", onRejected);
 
     resolver->resolve("bye");
     resolver->reject("bye");
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ("hello", onRejected);
@@ -196,7 +196,7 @@
     }
 
     resolver->resolve("hello");
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -321,7 +321,7 @@
     }
 
     resolver->resolve();
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -345,7 +345,7 @@
     }
 
     resolver->reject();
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ("undefined", onRejected);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp
index 73b38ba..a537ddc 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp
@@ -83,7 +83,7 @@
         createClosure(callback, v8::Undefined(m_scope.isolate()), m_scope.isolate());
 
         // Execute all pending microtasks
-        v8::MicrotasksScope::PerformCheckpoint(isolate());
+        isolate()->RunMicrotasks();
     }
 
     String toString(const ScriptValue& value)
@@ -124,13 +124,13 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     resolver.resolve(v8String(isolate(), "hello"));
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ("hello", toString(onFulfilled));
     EXPECT_TRUE(onRejected.isEmpty());
@@ -148,7 +148,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ("hello", toString(onFulfilled));
     EXPECT_TRUE(onRejected.isEmpty());
@@ -165,13 +165,13 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     resolver.reject(v8String(isolate(), "hello"));
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("hello", toString(onRejected));
@@ -189,7 +189,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("hello", toString(onRejected));
@@ -226,7 +226,7 @@
     EXPECT_TRUE(onRejected1.isEmpty());
     EXPECT_TRUE(onRejected2.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ("hello", toString(onFulfilled1));
     EXPECT_EQ("hello", toString(onFulfilled2));
@@ -248,7 +248,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("hello", toString(onRejected));
@@ -264,7 +264,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("SyntaxError: some syntax error", toString(onRejected));
@@ -282,7 +282,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_FALSE(onFulfilled.isEmpty());
     EXPECT_TRUE(toStringArray(onFulfilled).isEmpty());
@@ -304,7 +304,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_FALSE(onFulfilled.isEmpty());
     Vector<String> values = toStringArray(onFulfilled);
@@ -329,7 +329,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_FALSE(onRejected.isEmpty());
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
index 3f5bc4b..696a886 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
@@ -321,7 +321,7 @@
 
     v8::Debug::SetLiveEditEnabled(isolate, false);
 
-    isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped);
+    isolate->SetAutorunMicrotasks(false);
 }
 
 namespace {
@@ -378,15 +378,14 @@
     if (v8::HeapProfiler* profiler = isolate->GetHeapProfiler())
         profiler->SetWrapperClassInfoProvider(WrapperTypeInfo::NodeClassId, &RetainedDOMInfo::createRetainedDOMInfo);
 
-    ASSERT(ThreadState::current());
-    ThreadState::current()->addInterruptor(adoptPtr(new V8IsolateInterruptor(isolate)));
-    ThreadState::current()->registerTraceDOMWrappers(isolate, V8GCController::traceDOMWrappers);
+    ASSERT(ThreadState::mainThreadState());
+    ThreadState::mainThreadState()->addInterruptor(adoptPtr(new V8IsolateInterruptor(isolate)));
+    ThreadState::mainThreadState()->registerTraceDOMWrappers(isolate, V8GCController::traceDOMWrappers);
 }
 
 void V8Initializer::shutdownMainThread()
 {
     ASSERT(isMainThread());
-    ThreadState::current()->unregisterTraceDOMWrappers();
     v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate();
     V8PerIsolateData::willBeDestroyed(isolate);
     V8PerIsolateData::destroy(isolate);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
index 65c02bc..0a2cfcb9 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
@@ -30,6 +30,7 @@
 #include "bindings/core/v8/V8Binding.h"
 #include "bindings/core/v8/V8HiddenValue.h"
 #include "bindings/core/v8/V8ObjectConstructor.h"
+#include "bindings/core/v8/V8RecursionScope.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
 #include "core/frame/Deprecation.h"
 #include "core/inspector/MainThreadDebugger.h"
@@ -52,6 +53,18 @@
     V8PerIsolateData::from(isolate)->runEndOfScopeTasks();
 }
 
+#if ENABLE(ASSERT)
+static void assertV8RecursionScope(v8::Isolate* isolate)
+{
+    ASSERT(V8RecursionScope::properlyUsed(isolate));
+}
+
+static bool runningUnitTest()
+{
+    return Platform::current()->unitTestSupport();
+}
+#endif
+
 static void useCounterCallback(v8::Isolate* isolate, v8::Isolate::UseCounterFeature feature)
 {
     UseCounter::Feature blinkFeature;
@@ -130,15 +143,25 @@
 }
 
 V8PerIsolateData::V8PerIsolateData()
-    : m_isolateHolder(adoptPtr(new gin::IsolateHolder()))
+    : m_destructionPending(false)
+    , m_isolateHolder(adoptPtr(new gin::IsolateHolder()))
     , m_stringCache(adoptPtr(new StringCache(isolate())))
     , m_hiddenValue(V8HiddenValue::create())
     , m_constructorMode(ConstructorMode::CreateNewObject)
+    , m_recursionLevel(0)
     , m_isHandlingRecursionLevelError(false)
     , m_isReportingException(false)
+#if ENABLE(ASSERT)
+    , m_internalScriptRecursionLevel(0)
+#endif
+    , m_performingMicrotaskCheckpoint(false)
 {
     // FIXME: Remove once all v8::Isolate::GetCurrent() calls are gone.
     isolate()->Enter();
+#if ENABLE(ASSERT)
+    if (!runningUnitTest())
+        isolate()->AddCallCompletedCallback(&assertV8RecursionScope);
+#endif
     isolate()->AddBeforeCallEnteredCallback(&beforeCallEnteredCallback);
     isolate()->AddMicrotasksCompletedCallback(&microtasksCompletedCallback);
     if (isMainThread())
@@ -183,6 +206,9 @@
 {
     V8PerIsolateData* data = from(isolate);
 
+    ASSERT(!data->m_destructionPending);
+    data->m_destructionPending = true;
+
     data->m_threadDebugger.clear();
     // Clear any data that may have handles into the heap,
     // prior to calling ThreadState::detach().
@@ -193,6 +219,10 @@
 // gets called but before the Isolate exits.
 void V8PerIsolateData::destroy(v8::Isolate* isolate)
 {
+#if ENABLE(ASSERT)
+    if (!runningUnitTest())
+        isolate->RemoveCallCompletedCallback(&assertV8RecursionScope);
+#endif
     isolate->RemoveBeforeCallEnteredCallback(&beforeCallEnteredCallback);
     isolate->RemoveMicrotasksCompletedCallback(&microtasksCompletedCallback);
     V8PerIsolateData* data = from(isolate);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
index 2cda3f4..090fc856 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
@@ -74,18 +74,31 @@
 
     static void enableIdleTasks(v8::Isolate*, PassOwnPtr<gin::V8IdleTaskRunner>);
 
+    bool destructionPending() const { return m_destructionPending; }
     v8::Isolate* isolate() { return m_isolateHolder->isolate(); }
 
     StringCache* getStringCache() { return m_stringCache.get(); }
 
     v8::Persistent<v8::Value>& ensureLiveRoot();
 
+    int recursionLevel() const { return m_recursionLevel; }
+    int incrementRecursionLevel() { return ++m_recursionLevel; }
+    int decrementRecursionLevel() { return --m_recursionLevel; }
     bool isHandlingRecursionLevelError() const { return m_isHandlingRecursionLevelError; }
     void setIsHandlingRecursionLevelError(bool value) { m_isHandlingRecursionLevelError = value; }
 
     bool isReportingException() const { return m_isReportingException; }
     void setReportingException(bool value) { m_isReportingException = value; }
 
+    bool performingMicrotaskCheckpoint() const { return m_performingMicrotaskCheckpoint; }
+    void setPerformingMicrotaskCheckpoint(bool performingMicrotaskCheckpoint) { m_performingMicrotaskCheckpoint = performingMicrotaskCheckpoint; }
+
+#if ENABLE(ASSERT)
+    int internalScriptRecursionLevel() const { return m_internalScriptRecursionLevel; }
+    int incrementInternalScriptRecursionLevel() { return ++m_internalScriptRecursionLevel; }
+    int decrementInternalScriptRecursionLevel() { return --m_internalScriptRecursionLevel; }
+#endif
+
     V8HiddenValue* hiddenValue() { return m_hiddenValue.get(); }
 
     v8::Local<v8::FunctionTemplate> domTemplate(const void* domTemplateKey, v8::FunctionCallback = 0, v8::Local<v8::Value> data = v8::Local<v8::Value>(), v8::Local<v8::Signature> = v8::Local<v8::Signature>(), int length = 0);
@@ -118,6 +131,7 @@
     bool hasInstance(const WrapperTypeInfo* untrusted, v8::Local<v8::Value>, DOMTemplateMap&);
     v8::Local<v8::Object> findInstanceInPrototypeChain(const WrapperTypeInfo*, v8::Local<v8::Value>, DOMTemplateMap&);
 
+    bool m_destructionPending;
     OwnPtr<gin::IsolateHolder> m_isolateHolder;
     DOMTemplateMap m_domTemplateMapForMainWorld;
     DOMTemplateMap m_domTemplateMapForNonMainWorld;
@@ -129,9 +143,15 @@
     bool m_constructorMode;
     friend class ConstructorMode;
 
+    int m_recursionLevel;
     bool m_isHandlingRecursionLevelError;
     bool m_isReportingException;
 
+#if ENABLE(ASSERT)
+    int m_internalScriptRecursionLevel;
+#endif
+    bool m_performingMicrotaskCheckpoint;
+
     Vector<OwnPtr<EndOfScopeTask>> m_endOfScopeTasks;
     OwnPtr<ThreadDebugger> m_threadDebugger;
 };
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp
index b4c3acf7..ed10e86 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp
@@ -30,6 +30,13 @@
 
 #include "bindings/core/v8/V8RecursionScope.h"
 
+#include "core/dom/Microtask.h"
+
 namespace blink {
 
+void V8RecursionScope::didLeaveScriptContext()
+{
+    Microtask::performCheckpoint(m_isolate);
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h
index 8bbd26c..dd9a51f 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h
@@ -59,39 +59,63 @@
     STACK_ALLOCATED();
 public:
     explicit V8RecursionScope(v8::Isolate* isolate)
-        : m_scope(isolate, v8::MicrotasksScope::kRunMicrotasks)
+        : m_isolate(isolate)
     {
-        ASSERT(isolate->GetMicrotasksPolicy() == v8::MicrotasksPolicy::kScoped);
+        V8PerIsolateData::from(m_isolate)->incrementRecursionLevel();
+        // If you want V8 to autorun microtasks, this class needs to have a
+        // v8::Isolate::SuppressMicrotaskExecutionScope member.
+        ASSERT(!isolate->WillAutorunMicrotasks());
     }
 
     ~V8RecursionScope()
     {
+        if (!V8PerIsolateData::from(m_isolate)->decrementRecursionLevel())
+            didLeaveScriptContext();
     }
 
     static int recursionLevel(v8::Isolate* isolate)
     {
-        return v8::MicrotasksScope::GetCurrentDepth(isolate);
+        return V8PerIsolateData::from(isolate)->recursionLevel();
     }
 
+#if ENABLE(ASSERT)
+    static bool properlyUsed(v8::Isolate* isolate)
+    {
+        return recursionLevel(isolate) > 0 || V8PerIsolateData::from(isolate)->internalScriptRecursionLevel() > 0;
+    }
+#endif
+
     class MicrotaskSuppression {
         USING_FAST_MALLOC(MicrotaskSuppression);
         WTF_MAKE_NONCOPYABLE(MicrotaskSuppression);
     public:
-        explicit MicrotaskSuppression(v8::Isolate* isolate)
-            : m_scope(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks)
+        MicrotaskSuppression(v8::Isolate* isolate)
+#if ENABLE(ASSERT)
+            : m_isolate(isolate)
+#endif
         {
+#if ENABLE(ASSERT)
+            V8PerIsolateData::from(m_isolate)->incrementInternalScriptRecursionLevel();
+#endif
         }
 
         ~MicrotaskSuppression()
         {
+#if ENABLE(ASSERT)
+            V8PerIsolateData::from(m_isolate)->decrementInternalScriptRecursionLevel();
+#endif
         }
 
     private:
-        v8::MicrotasksScope m_scope;
+#if ENABLE(ASSERT)
+        v8::Isolate* m_isolate;
+#endif
     };
 
 private:
-    v8::MicrotasksScope m_scope;
+    void didLeaveScriptContext();
+
+    v8::Isolate* m_isolate;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h b/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
index a626a0d..d9f9830 100644
--- a/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
+++ b/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
@@ -135,15 +135,6 @@
         MOCK_METHOD0(createAnimationPlayer, CompositorAnimationPlayer*());
         MOCK_METHOD0(createAnimationTimeline, CompositorAnimationTimeline*());
     };
-
-private:
-    TestingPlatformSupport m_proxyPlatform;
-
-protected:
-    void SetUp() override
-    {
-        Platform::initialize(&m_proxyPlatform);
-    }
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index 241cca4..3cdb438 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -1610,6 +1610,8 @@
             'fetch/LinkFetchResource.h',
             'fetch/MemoryCache.cpp',
             'fetch/MemoryCache.h',
+            'fetch/MultipartImageResourceParser.cpp',
+            'fetch/MultipartImageResourceParser.h',
             'fetch/RawResource.cpp',
             'fetch/RawResource.h',
             'fetch/Resource.cpp',
@@ -3959,6 +3961,7 @@
             'fetch/ImageResourceTest.cpp',
             'fetch/MemoryCacheTest.cpp',
             'fetch/MockImageResourceClient.cpp',
+            'fetch/MultipartImageResourceParserTest.cpp',
             'fetch/RawResourceTest.cpp',
             'fetch/ResourceFetcherTest.cpp',
             'fetch/ResourceLoaderOptionsTest.cpp',
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 3e2e08c5..85872f1 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -2322,31 +2322,14 @@
 
 Document& Document::axObjectCacheOwner() const
 {
-    // FIXME(dmazzoni): Currently there's one AXObjectCache per page, owned
-    // by the top document, but with --site-isolation the top document may
-    // be a remote frame. As a quick fix we're making the local root the owner
-    // of the AXObjectCache (http://crbug.com/510410), but the proper fix
-    // will be for each Document to  have its own AXObjectCache
-    // (http://crbug.com/532249).
-    Document* top = const_cast<Document*>(this);
-    LocalFrame* frame = this->frame();
-    if (!frame)
-        return *top;
-
-    // This loop is more efficient than calling localFrameRoot.
-    while (frame && frame->owner() && frame->owner()->isLocal()) {
-        HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(frame->owner());
-        top = &owner->document();
-        frame = top->frame();
+    // Every document has its own axObjectCache if accessibility is enabled,
+    // except for page popups, which share the axObjectCache of their owner.
+    Document* doc = const_cast<Document*>(this);
+    if (doc->frame() && doc->frame()->pagePopupOwner()) {
+        ASSERT(!doc->m_axObjectCache);
+        return doc->frame()->pagePopupOwner()->document().axObjectCacheOwner();
     }
-
-    if (top->frame() && top->frame()->pagePopupOwner()) {
-        ASSERT(!top->m_axObjectCache);
-        return top->frame()->pagePopupOwner()->document().axObjectCacheOwner();
-    }
-
-    ASSERT(top);
-    return *top;
+    return *doc;
 }
 
 void Document::clearAXObjectCache()
diff --git a/third_party/WebKit/Source/core/dom/IdleRequestCallback.h b/third_party/WebKit/Source/core/dom/IdleRequestCallback.h
index a30ba581..a54f3d0 100644
--- a/third_party/WebKit/Source/core/dom/IdleRequestCallback.h
+++ b/third_party/WebKit/Source/core/dom/IdleRequestCallback.h
@@ -20,7 +20,6 @@
 
     virtual void handleEvent(IdleDeadline*) = 0;
 };
-
 } // namespace blink
 
 #endif // IdleRequestCallback_h
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp b/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp
index 5b71c685..055b3c64 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserverController.cpp
@@ -5,7 +5,6 @@
 #include "core/dom/IntersectionObserverController.h"
 
 #include "core/dom/Document.h"
-#include "core/dom/IdleRequestOptions.h"
 
 namespace blink {
 
@@ -20,8 +19,8 @@
 
 IntersectionObserverController::IntersectionObserverController(Document* document)
     : ActiveDOMObject(document)
-    , m_callbackIsScheduled(false)
-    , m_callbackFiredWhileSuspended(false)
+    , m_timer(this, &IntersectionObserverController::deliverIntersectionObservations)
+    , m_timerFiredWhileSuspended(false)
 {
 }
 
@@ -29,39 +28,28 @@
 
 void IntersectionObserverController::scheduleIntersectionObserverForDelivery(IntersectionObserver& observer)
 {
+    // TODO(szager): use idle callback with a timeout.  Until we do that, there is no
+    // reliable way to write a test for takeRecords, because it's impossible to guarantee
+    // that javascript will get a chance to run before the timer fires.
+    if (!m_timer.isActive())
+        m_timer.startOneShot(0, BLINK_FROM_HERE);
     m_pendingIntersectionObservers.add(&observer);
-    if (m_callbackIsScheduled)
-        return;
-    Document* document = toDocument(getExecutionContext());
-    if (!document)
-        return;
-    m_callbackIsScheduled = true;
-    IdleRequestOptions options;
-    // The IntersectionObserver spec mandates that notifications be sent within 100ms.
-    options.setTimeout(100);
-    document->requestIdleCallback(this, options);
 }
 
 void IntersectionObserverController::resume()
 {
-    // If the callback fired while DOM objects were suspended, notifications might be late, so deliver
-    // them right away (rather than waiting to fire again).
-    if (m_callbackFiredWhileSuspended) {
-        m_callbackFiredWhileSuspended = false;
-        deliverIntersectionObservations();
+    // If the timer fired while DOM objects were suspended, notifications might be late, so deliver
+    // them right away (rather than waiting for m_timer to fire again).
+    if (m_timerFiredWhileSuspended) {
+        m_timerFiredWhileSuspended = false;
+        deliverIntersectionObservations(nullptr);
     }
 }
 
-void IntersectionObserverController::handleEvent(IdleDeadline*)
-{
-    m_callbackIsScheduled = false;
-    deliverIntersectionObservations();
-}
-
-void IntersectionObserverController::deliverIntersectionObservations()
+void IntersectionObserverController::deliverIntersectionObservations(Timer<IntersectionObserverController>*)
 {
     if (getExecutionContext()->activeDOMObjectsAreSuspended()) {
-        m_callbackFiredWhileSuspended = true;
+        m_timerFiredWhileSuspended = true;
         return;
     }
     IntersectionObserverVector observers;
@@ -100,7 +88,6 @@
     visitor->trace(m_trackedIntersectionObservers);
     visitor->trace(m_pendingIntersectionObservers);
     ActiveDOMObject::trace(visitor);
-    IdleRequestCallback::trace(visitor);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserverController.h b/third_party/WebKit/Source/core/dom/IntersectionObserverController.h
index 089f9fa..554f574b 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObserverController.h
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserverController.h
@@ -7,8 +7,8 @@
 
 #include "core/dom/ActiveDOMObject.h"
 #include "core/dom/Element.h"
-#include "core/dom/IdleRequestCallback.h"
 #include "core/dom/IntersectionObserver.h"
+#include "platform/Timer.h"
 #include "platform/heap/Handle.h"
 #include "wtf/HashSet.h"
 
@@ -17,17 +17,16 @@
 
 namespace blink {
 
-class IntersectionObserverController : public IdleRequestCallback, public ActiveDOMObject {
+class IntersectionObserverController : public GarbageCollectedFinalized<IntersectionObserverController>, public ActiveDOMObject {
     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(IntersectionObserverController);
 public:
     static IntersectionObserverController* create(Document*);
     ~IntersectionObserverController();
 
     void resume() override;
-    void handleEvent(IdleDeadline*) override;
 
     void scheduleIntersectionObserverForDelivery(IntersectionObserver&);
-    void deliverIntersectionObservations();
+    void deliverIntersectionObservations(Timer<IntersectionObserverController>*);
     void computeTrackedIntersectionObservations();
     void addTrackedObserver(IntersectionObserver&);
     void removeTrackedObserversForRoot(const Node&);
@@ -38,13 +37,13 @@
     explicit IntersectionObserverController(Document*);
 
 private:
+    Timer<IntersectionObserverController> m_timer;
     // IntersectionObservers for which this is the tracking document.
     HeapHashSet<WeakMember<IntersectionObserver>> m_trackedIntersectionObservers;
     // IntersectionObservers for which this is the execution context of the callback.
     HeapHashSet<Member<IntersectionObserver>> m_pendingIntersectionObservers;
 
-    bool m_callbackIsScheduled;
-    bool m_callbackFiredWhileSuspended;
+    bool m_timerFiredWhileSuspended;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/Microtask.cpp b/third_party/WebKit/Source/core/dom/Microtask.cpp
index 344c9e01..7c3ec6ed 100644
--- a/third_party/WebKit/Source/core/dom/Microtask.cpp
+++ b/third_party/WebKit/Source/core/dom/Microtask.cpp
@@ -40,9 +40,13 @@
 
 void Microtask::performCheckpoint(v8::Isolate* isolate)
 {
-    if (ScriptForbiddenScope::isScriptForbidden())
+    V8PerIsolateData* isolateData = V8PerIsolateData::from(isolate);
+    ASSERT(isolateData);
+    if (isolateData->recursionLevel() || isolateData->performingMicrotaskCheckpoint() || isolateData->destructionPending() || ScriptForbiddenScope::isScriptForbidden())
         return;
-    v8::MicrotasksScope::PerformCheckpoint(isolate);
+    isolateData->setPerformingMicrotaskCheckpoint(true);
+    isolate->RunMicrotasks();
+    isolateData->setPerformingMicrotaskCheckpoint(false);
 }
 
 static void microtaskFunctionCallback(void* data)
diff --git a/third_party/WebKit/Source/core/dom/Node.idl b/third_party/WebKit/Source/core/dom/Node.idl
index 2be0da1..12251c59 100644
--- a/third_party/WebKit/Source/core/dom/Node.idl
+++ b/third_party/WebKit/Source/core/dom/Node.idl
@@ -51,7 +51,7 @@
     [PerWorldBindings] readonly attribute Node? lastChild;
     [PerWorldBindings] readonly attribute Node? previousSibling;
     [PerWorldBindings] readonly attribute Node? nextSibling;
-    [RuntimeEnabled=ShadowDOMV1, MeasureAs=NodeRootNode, ImplementedAs=treeRoot] readonly attribute Node rootNode;
+    [MeasureAs=NodeRootNode, ImplementedAs=treeRoot] readonly attribute Node rootNode;
 
     [CustomElementCallbacks] attribute DOMString? nodeValue;
     // FIXME: textContent should not have [TreatUndefinedAs=NullString].
diff --git a/third_party/WebKit/Source/core/editing/Selection.idl b/third_party/WebKit/Source/core/editing/Selection.idl
index e2c3a23..7466f32c 100644
--- a/third_party/WebKit/Source/core/editing/Selection.idl
+++ b/third_party/WebKit/Source/core/editing/Selection.idl
@@ -47,18 +47,18 @@
     //void removeRange(Range range);
     [MeasureAs=SelectionRemoveAllRanges] void removeAllRanges();
     [MeasureAs=SelectionEmpty] void empty();
-    [MeasureAs=SelectionCollapse, RaisesException, LegacyInterfaceTypeChecking] void collapse(Node? node, optional long offset = 0);
-    [ImplementedAs=collapse, MeasureAs=SelectionSetPosition, RaisesException, LegacyInterfaceTypeChecking] void setPosition(Node? node, optional long offset = 0);
+    [MeasureAs=SelectionCollapse, RaisesException] void collapse(Node? node, optional long offset = 0);
+    [ImplementedAs=collapse, MeasureAs=SelectionSetPosition, RaisesException] void setPosition(Node? node, optional long offset = 0);
     [MeasureAs=SelectionCollapseToStart, RaisesException] void collapseToStart();
     [MeasureAs=SelectionCollapseToEnd, RaisesException] void collapseToEnd();
     [MeasureAs=SelectionExtend, RaisesException] void extend(Node node, optional long offset = 0);
     // TODO(philipj): The arguments should be anchorNode, anchorOffset,
     // focusNode and focusOffset, and none of them are optional or nullable in
     // the spec.
-    [MeasureAs=SelectionSetBaseAndExtent, RaisesException, LegacyInterfaceTypeChecking] void setBaseAndExtent([Default=Undefined] optional Node? baseNode,
-                                                                                                              [Default=Undefined] optional long baseOffset,
-                                                                                                              [Default=Undefined] optional Node? extentNode,
-                                                                                                              [Default=Undefined] optional long extentOffset);
+    [MeasureAs=SelectionSetBaseAndExtent, RaisesException] void setBaseAndExtent([Default=Undefined] optional Node? baseNode,
+                                                                                 [Default=Undefined] optional long baseOffset,
+                                                                                 [Default=Undefined] optional Node? extentNode,
+                                                                                 [Default=Undefined] optional long extentOffset);
     [MeasureAs=SelectionSelectAllChildren, RaisesException] void selectAllChildren(Node node);
     [MeasureAs=SelectionDeleteDromDocument, CustomElementCallbacks] void deleteFromDocument();
     [MeasureAs=SelectionContainsNode] boolean containsNode(Node node, optional boolean allowPartialContainment = false);
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
index a44d16f..150706e 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -2273,146 +2273,17 @@
     return false;
 }
 
-static Node* nextRenderedEditable(Node* node)
-{
-    for (node = nextAtomicLeafNode(*node); node; node = nextAtomicLeafNode(*node)) {
-        LayoutObject* layoutObject = node->layoutObject();
-        if (!layoutObject)
-            continue;
-        if (!node->hasEditableStyle())
-            continue;
-        // TODO(yosin) We should have a function to check |InlineBox| types
-        // in layout rather than using |InlineBox| here. See also
-        // |previousRenderedEditable()| which has a same condition.
-        if ((layoutObject->isBox() && toLayoutBox(layoutObject)->inlineBoxWrapper()) || (layoutObject->isText() && toLayoutText(layoutObject)->hasTextBoxes()))
-            return node;
-    }
-    return 0;
-}
-
-static Node* previousRenderedEditable(Node* node)
-{
-    for (node = previousAtomicLeafNode(*node); node; node = previousAtomicLeafNode(*node)) {
-        LayoutObject* layoutObject = node->layoutObject();
-        if (!layoutObject)
-            continue;
-        if (!node->hasEditableStyle())
-            continue;
-        // TODO(yosin) We should have a function to check |InlineBox| types
-        // in layout rather than using |InlineBox| here. See also
-        // |nextRenderedEditable()| which has a same condition.
-        if ((layoutObject->isBox() && toLayoutBox(layoutObject)->inlineBoxWrapper()) || (layoutObject->isText() && toLayoutText(layoutObject)->hasTextBoxes()))
-            return node;
-    }
-    return 0;
-}
-
-static int renderedOffsetOf(const Position& position)
-{
-    const int offset = position.computeEditingOffset();
-    Node* const anchorNode = position.anchorNode();
-    if (!anchorNode->isTextNode() || !anchorNode->layoutObject())
-        return offset;
-
-    // TODO(yosin) We should have a function to compute offset in |LayoutText|
-    // to avoid using |InlineBox| in "editing/".
-    int result = 0;
-    LayoutText* textLayoutObject = toLayoutText(anchorNode->layoutObject());
-    for (InlineTextBox *box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox()) {
-        int start = box->start();
-        int end = box->start() + box->len();
-        if (offset < start)
-            return result;
-        if (offset <= end) {
-            result += offset - start;
-            return result;
-        }
-        result += box->len();
-    }
-    return result;
-}
-
-// TODO(yosin) We should move |rendersInDifferentPosition()to "EditingUtilities.cpp"
-// with |renderedOffsetOf()|.
 bool rendersInDifferentPosition(const Position& position1, const Position& position2)
 {
     if (position1.isNull() || position2.isNull())
         return false;
-
-    LayoutObject* layoutObject = position1.anchorNode()->layoutObject();
-    if (!layoutObject)
-        return false;
-
-    LayoutObject* posLayoutObject = position2.anchorNode()->layoutObject();
-    if (!posLayoutObject)
-        return false;
-
-    if (layoutObject->style()->visibility() != VISIBLE
-        || posLayoutObject->style()->visibility() != VISIBLE)
-        return false;
-
-    if (position1.anchorNode() == position2.anchorNode()) {
-        if (isHTMLBRElement(*position1.anchorNode()))
-            return false;
-
-        if (position1.computeEditingOffset() == position2.computeEditingOffset())
-            return false;
-
-        if (!position1.anchorNode()->isTextNode() && !position2.anchorNode()->isTextNode())
-            return true;
-    }
-
-    if (isHTMLBRElement(*position1.anchorNode()) && isVisuallyEquivalentCandidate(position2))
-        return true;
-
-    if (isHTMLBRElement(*position2.anchorNode()) && isVisuallyEquivalentCandidate(position1))
-        return true;
-
-    if (!inSameContainingBlockFlowElement(position1.anchorNode(), position2.anchorNode()))
-        return true;
-
-    if (position1.anchorNode()->isTextNode() && !inRenderedText(position1))
-        return false;
-
-    if (position2.anchorNode()->isTextNode() && !inRenderedText(position2))
-        return false;
-
-    const int renderedOffset1 = renderedOffsetOf(position1);
-    const int renderedOffset2 = renderedOffsetOf(position2);
-
-    if (layoutObject == posLayoutObject && renderedOffset1 == renderedOffset2)
-        return false;
-
-    InlineBoxPosition boxPosition1 = computeInlineBoxPosition(position1, TextAffinity::Downstream);
-    InlineBoxPosition boxPosition2 = computeInlineBoxPosition(position2, TextAffinity::Downstream);
-
-    WTF_LOG(Editing, "layoutObject1:   %p [%p]\n", layoutObject, boxPosition1.inlineBox);
-    WTF_LOG(Editing, "renderedOffset1: %d\n", renderedOffset1);
-    WTF_LOG(Editing, "layoutObject2:   %p [%p]\n", posLayoutObject, boxPosition2.inlineBox);
-    WTF_LOG(Editing, "renderedOffset2: %d\n", renderedOffset2);
-    WTF_LOG(Editing, "node1 min/max:   %d:%d\n", caretMinOffset(position1.anchorNode()), caretMaxOffset(position1.anchorNode()));
-    WTF_LOG(Editing, "node2 min/max:   %d:%d\n", caretMinOffset(position2.anchorNode()), caretMaxOffset(position2.anchorNode()));
-    WTF_LOG(Editing, "----------------------------------------------------------------------\n");
-
-    if (!boxPosition1.inlineBox || !boxPosition2.inlineBox) {
-        return false;
-    }
-
-    if (boxPosition1.inlineBox->root() != boxPosition2.inlineBox->root()) {
-        return true;
-    }
-
-    if (nextRenderedEditable(position1.anchorNode()) == position2.anchorNode()
-        && renderedOffset1 == caretMaxOffset(position1.anchorNode()) && !renderedOffset2) {
-        return false;
-    }
-
-    if (previousRenderedEditable(position1.anchorNode()) == position2.anchorNode()
-        && !renderedOffset1 && renderedOffset2 == caretMaxOffset(position2.anchorNode())) {
-        return false;
-    }
-
-    return true;
+    LayoutObject* layoutObject1;
+    const LayoutRect& rect1 = localCaretRectOfPosition(PositionWithAffinity(position1), layoutObject1);
+    LayoutObject* layoutObject2;
+    const LayoutRect& rect2 = localCaretRectOfPosition(PositionWithAffinity(position2), layoutObject2);
+    if (!layoutObject1 || !layoutObject2)
+        return layoutObject1 != layoutObject2;
+    return layoutObject1->localToAbsoluteQuad(FloatRect(rect1)) != layoutObject2->localToAbsoluteQuad(FloatRect(rect2));
 }
 
 static bool isVisuallyEmpty(const LayoutObject* layout)
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp b/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp
index 815a92af..7f902f7c 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp
@@ -1090,10 +1090,38 @@
     updateLayoutAndStyleForPainting();
     RefPtrWillBeRawPtr<Element> sample = document().getElementById("sample");
 
+    EXPECT_FALSE(rendersInDifferentPosition(Position(), Position()));
+    EXPECT_FALSE(rendersInDifferentPosition(Position(), Position::afterNode(sample.get())))
+        << "if one of position is null, the reuslt is false.";
     EXPECT_FALSE(rendersInDifferentPosition(Position::afterNode(sample.get()), Position(sample.get(), 1)));
     EXPECT_FALSE(rendersInDifferentPosition(Position::lastPositionInNode(sample.get()), Position(sample.get(), 1)));
 }
 
+TEST_F(VisibleUnitsTest, rendersInDifferentPositionAfterAnchorWithHidden)
+{
+    const char* bodyContent = "<p><span id=one>11</span><span id=two style='display:none'>  </span></p>";
+    setBodyContent(bodyContent);
+    updateLayoutAndStyleForPainting();
+    RefPtrWillBeRawPtr<Element> one = document().getElementById("one");
+    RefPtrWillBeRawPtr<Element> two = document().getElementById("two");
+
+    EXPECT_TRUE(rendersInDifferentPosition(Position::lastPositionInNode(one.get()), Position(two.get(), 0)))
+        << "two doesn't have layout object";
+}
+
+TEST_F(VisibleUnitsTest, rendersInDifferentPositionAfterAnchorWithDifferentLayoutObjects)
+{
+    const char* bodyContent = "<p><span id=one>11</span><span id=two>  </span></p>";
+    setBodyContent(bodyContent);
+    updateLayoutAndStyleForPainting();
+    RefPtrWillBeRawPtr<Element> one = document().getElementById("one");
+    RefPtrWillBeRawPtr<Element> two = document().getElementById("two");
+
+    EXPECT_FALSE(rendersInDifferentPosition(Position::lastPositionInNode(one.get()), Position(two.get(), 0)));
+    EXPECT_FALSE(rendersInDifferentPosition(Position::lastPositionInNode(one.get()), Position(two.get(), 1)))
+        << "width of two is zero since contents is collapsed whitespaces";
+}
+
 TEST_F(VisibleUnitsTest, renderedOffset)
 {
     const char* bodyContent = "<div contenteditable><span id='sample1'>1</span><span id='sample2'>22</span></div>";
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp
index 52210eb5..44c6fd9 100644
--- a/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp
@@ -36,6 +36,7 @@
 #include "core/frame/LocalFrame.h"
 #include "core/html/HTMLBRElement.h"
 #include "core/html/HTMLElement.h"
+#include "core/html/HTMLTextFormControlElement.h"
 #include "core/layout/LayoutObject.h"
 #include "core/layout/LayoutText.h"
 
@@ -60,7 +61,7 @@
     // the input element, and in that case we need to check the input element's
     // parent's layoutObject.
     Position p(insertionPos.parentAnchoredEquivalent());
-    return p.anchorNode()->layoutObject() && !p.anchorNode()->layoutObject()->style()->preserveNewline();
+    return isRichlyEditablePosition(p) && p.anchorNode()->layoutObject() && !p.anchorNode()->layoutObject()->style()->preserveNewline();
 }
 
 void InsertLineBreakCommand::doApply(EditingState* editingState)
@@ -102,9 +103,16 @@
             return;
 
         if (needExtraLineBreak) {
-            insertNodeBefore(nodeToInsert->cloneNode(false), nodeToInsert, editingState);
+            RefPtrWillBeRawPtr<Node> extraNode;
+            // TODO(tkent): Can we remove HTMLTextFormControlElement dependency?
+            if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(nodeToInsert.get()))
+                extraNode = textControl->createPlaceholderBreakElement();
+            else
+                extraNode = nodeToInsert->cloneNode(false);
+            insertNodeAfter(extraNode.get(), nodeToInsert, editingState);
             if (editingState->isAborted())
                 return;
+            nodeToInsert = extraNode.release();
         }
 
         VisiblePosition endingPosition = createVisiblePosition(positionBeforeNode(nodeToInsert.get()));
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp
index ab934f9..e067f8b 100644
--- a/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp
@@ -191,7 +191,7 @@
 
     Position endPosition;
 
-    if (m_text == "\t") {
+    if (m_text == "\t" && isRichlyEditablePosition(startPosition)) {
         endPosition = insertTab(startPosition, editingState);
         if (editingState->isAborted())
             return;
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
index d85b5ea..d9fce93 100644
--- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
@@ -1313,6 +1313,11 @@
                     if (editingState->isAborted())
                         return;
                     setEndingSelection(createVisiblePosition(firstPositionInNode(newListItem.get())));
+                } else if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(enclosingBlockElement)) {
+                    insertNodeAfter(textControl->createPlaceholderBreakElement(), insertedNodes.lastLeafInserted(), editingState);
+                    if (editingState->isAborted())
+                        return;
+                    setEndingSelection(createVisiblePosition(positionAfterNode(insertedNodes.lastLeafInserted())));
                 } else {
                     // Use a default paragraph element (a plain div) for the empty paragraph, using the last paragraph
                     // block's style seems to annoy users.
diff --git a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.cpp b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.cpp
new file mode 100644
index 0000000..266edfd9
--- /dev/null
+++ b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.cpp
@@ -0,0 +1,201 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fetch/MultipartImageResourceParser.h"
+
+#include "public/platform/Platform.h"
+#include "public/platform/WebURLResponse.h"
+#include "wtf/NotFound.h"
+#include "wtf/text/WTFString.h"
+
+#include <algorithm>
+
+namespace blink {
+
+MultipartImageResourceParser::MultipartImageResourceParser(const ResourceResponse& response, const Vector<char>& boundary, Client* client)
+    : m_originalResponse(response)
+    , m_boundary(boundary)
+    , m_client(client)
+{
+    // Some servers report a boundary prefixed with "--".  See https://crbug.com/5786.
+    if (m_boundary.size() < 2 || m_boundary[0] != '-' || m_boundary[1] != '-')
+        m_boundary.prepend("--", 2);
+}
+
+void MultipartImageResourceParser::appendData(const char* bytes, size_t size)
+{
+    // m_sawLastBoundary means that we've already received the final boundary
+    // token. The server should stop sending us data at this point, but if it
+    // does, we just throw it away.
+    if (m_sawLastBoundary)
+        return;
+    m_data.append(bytes, size);
+
+    if (m_isParsingTop) {
+        // Eat leading \r\n
+        size_t pos = pushOverLine(m_data, 0);
+        if (pos)
+            m_data.remove(0, pos);
+
+        if (m_data.size() < m_boundary.size() + 2) {
+            // We don't have enough data yet to make a boundary token.  Just
+            // wait until the next chunk of data arrives.
+            return;
+        }
+
+        // Some servers don't send a boundary token before the first chunk of
+        // data.  We handle this case anyway (Gecko does too).
+        if (0 != memcmp(m_data.data(), m_boundary.data(), m_boundary.size())) {
+            m_data.prepend("\n", 1);
+            m_data.prependVector(m_boundary);
+        }
+        m_isParsingTop = false;
+    }
+
+    // Headers
+    if (m_isParsingHeaders) {
+        // Eat leading \r\n
+        size_t pos = pushOverLine(m_data, 0);
+        if (pos)
+            m_data.remove(0, pos);
+
+        if (!parseHeaders()) {
+            // Get more data before trying again.
+            return;
+        }
+        // Successfully parsed headers.
+        m_isParsingHeaders = false;
+        if (isCancelled())
+            return;
+    }
+
+    size_t boundaryPosition;
+    while ((boundaryPosition = findBoundary(m_data, &m_boundary)) != kNotFound) {
+        // Strip out trailing \r\n characters in the buffer preceding the
+        // boundary on the same lines as does Firefox.
+        size_t dataSize = boundaryPosition;
+        if (boundaryPosition > 0 && m_data[boundaryPosition - 1] == '\n') {
+            dataSize--;
+            if (boundaryPosition > 1 && m_data[boundaryPosition - 2] == '\r') {
+                dataSize--;
+            }
+        }
+        if (dataSize) {
+            m_client->multipartDataReceived(m_data.data(), dataSize);
+            if (isCancelled())
+                return;
+        }
+        size_t boundaryEndPosition = boundaryPosition + m_boundary.size();
+        if (boundaryEndPosition < m_data.size() && '-' == m_data[boundaryEndPosition]) {
+            // This was the last boundary so we can stop processing.
+            m_sawLastBoundary = true;
+            m_data.clear();
+            return;
+        }
+
+        // We can now throw out data up through the boundary
+        size_t offset = pushOverLine(m_data, boundaryEndPosition);
+        m_data.remove(0, boundaryEndPosition + offset);
+
+        // Ok, back to parsing headers
+        if (!parseHeaders()) {
+            m_isParsingHeaders = true;
+            break;
+        }
+    }
+
+    // At this point, we should send over any data we have, but keep enough data
+    // buffered to handle a boundary that may have been truncated.
+    if (!m_isParsingHeaders && m_data.size() > m_boundary.size()) {
+        // If the last character is a new line character, go ahead and just send
+        // everything we have buffered.  This matches an optimization in Gecko.
+        size_t sendLength = m_data.size() - m_boundary.size();
+        if (m_data.last() == '\n')
+            sendLength = m_data.size();
+        m_client->multipartDataReceived(m_data.data(), sendLength);
+        m_data.remove(0, sendLength);
+    }
+}
+
+void MultipartImageResourceParser::finish()
+{
+    ASSERT(!isCancelled());
+    // If we have any pending data and we're not in a header, go ahead and send
+    // it to the client.
+    if (!m_isParsingHeaders && !m_data.isEmpty() && !m_sawLastBoundary)
+        m_client->multipartDataReceived(m_data.data(), m_data.size());
+    m_data.clear();
+    m_sawLastBoundary = true;
+}
+
+size_t MultipartImageResourceParser::pushOverLine(const Vector<char>& data, size_t pos)
+{
+    size_t offset = 0;
+    // TODO(yhirano): This function has two problems. Fix them.
+    //  1. It eats "\n\n".
+    //  2. When the incoming data is not sufficient (i.e. data[pos] == '\r'
+    //     && data.size() == pos + 1), it should notify the caller.
+    if (pos < data.size() && (data[pos] == '\r' || data[pos] == '\n')) {
+        ++offset;
+        if (pos + 1 < data.size() && data[pos + 1] == '\n')
+            ++offset;
+    }
+    return offset;
+}
+
+bool MultipartImageResourceParser::parseHeaders()
+{
+    // Create a WebURLResponse based on the original set of headers + the
+    // replacement headers. We only replace the same few headers that gecko
+    // does. See netwerk/streamconv/converters/nsMultiMixedConv.cpp.
+    WebURLResponse response(m_originalResponse.url());
+    for (const auto& header : m_originalResponse.httpHeaderFields())
+        response.addHTTPHeaderField(header.key, header.value);
+
+    size_t end = 0;
+    if (!Platform::current()->parseMultipartHeadersFromBody(m_data.data(), m_data.size(), &response, &end))
+        return false;
+    m_data.remove(0, end);
+
+    // To avoid recording every multipart load as a separate visit in
+    // the history database, we want to keep track of whether the response
+    // is part of a multipart payload.  We do want to record the first visit,
+    // so we only set isMultipartPayload to true after the first visit.
+    response.setIsMultipartPayload(!m_isFirstPart);
+    m_isFirstPart = false;
+    // Send the response!
+    m_client->onePartInMultipartReceived(response.toResourceResponse());
+
+    return true;
+}
+
+// Boundaries are supposed to be preceeded with --, but it looks like gecko
+// doesn't require the dashes to exist.  See nsMultiMixedConv::FindToken.
+size_t MultipartImageResourceParser::findBoundary(const Vector<char>& data, Vector<char>* boundary)
+{
+    auto it = std::search(data.data(), data.data() + data.size(), boundary->data(), boundary->data() + boundary->size());
+    if (it == data.data() + data.size())
+        return kNotFound;
+
+    size_t boundaryPosition = it - data.data();
+    // Back up over -- for backwards compat
+    // TODO(tc): Don't we only want to do this once?  Gecko code doesn't
+    // seem to care.
+    if (boundaryPosition >= 2) {
+        if (data[boundaryPosition - 1] == '-' && data[boundaryPosition - 2] == '-') {
+            boundaryPosition -= 2;
+            Vector<char> v(2, '-');
+            v.appendVector(*boundary);
+            *boundary = v;
+        }
+    }
+    return boundaryPosition;
+}
+
+DEFINE_TRACE(MultipartImageResourceParser)
+{
+    visitor->trace(m_client);
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.h b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.h
new file mode 100644
index 0000000..c812bb9
--- /dev/null
+++ b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.h
@@ -0,0 +1,94 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MultipartImageResourceParser_h
+#define MultipartImageResourceParser_h
+
+#include "core/CoreExport.h"
+#include "platform/heap/Handle.h"
+#include "platform/network/ResourceResponse.h"
+#include "wtf/Vector.h"
+
+namespace blink {
+
+// A parser parsing mlutipart/x-mixed-replace resource.
+class CORE_EXPORT MultipartImageResourceParser final : public GarbageCollectedFinalized<MultipartImageResourceParser> {
+    WTF_MAKE_NONCOPYABLE(MultipartImageResourceParser);
+public:
+    class CORE_EXPORT Client : public WillBeGarbageCollectedMixin {
+    public:
+        virtual ~Client() = default;
+        virtual void onePartInMultipartReceived(const ResourceResponse&) = 0;
+        virtual void multipartDataReceived(const char* bytes, size_t) = 0;
+        DEFINE_INLINE_VIRTUAL_TRACE() {}
+    };
+
+    MultipartImageResourceParser(const ResourceResponse&, const Vector<char>& boundary, Client*);
+    void appendData(const char* bytes, size_t);
+    void finish();
+    void cancel() { m_isCancelled = true; }
+
+    DECLARE_TRACE();
+
+    static size_t pushOverLineForTest(const Vector<char>& data, size_t size) { return pushOverLine(data, size); }
+    static size_t findBoundaryForTest(const Vector<char>& data, Vector<char>* boundary) { return findBoundary(data, boundary); }
+
+private:
+    bool parseHeaders();
+    bool isCancelled() const { return m_isCancelled; }
+    static size_t pushOverLine(const Vector<char>&, size_t);
+    // This function updates |*boundary|.
+    static size_t findBoundary(const Vector<char>& data, Vector<char>* boundary);
+
+    const ResourceResponse m_originalResponse;
+    Vector<char> m_boundary;
+    RawPtrWillBeMember<Client> m_client;
+
+    Vector<char> m_data;
+    bool m_isParsingTop = true;
+    bool m_isParsingHeaders = false;
+    bool m_sawLastBoundary = false;
+    bool m_isFirstPart = true;
+    bool m_isCancelled = false;
+};
+
+} // namespace blink
+
+#endif // MultipartImageResourceParser_h
diff --git a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp
new file mode 100644
index 0000000..6fb132f
--- /dev/null
+++ b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp
@@ -0,0 +1,479 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fetch/MultipartImageResourceParser.h"
+
+#include "platform/network/ResourceResponse.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebURL.h"
+#include "public/platform/WebURLResponse.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+namespace blink {
+
+namespace {
+
+String toString(const Vector<char>& data)
+{
+    if (data.isEmpty())
+        return String("");
+    return String(data.data(), data.size());
+}
+
+class MockClient final : public NoBaseWillBeGarbageCollectedFinalized<MockClient>, public MultipartImageResourceParser::Client {
+    WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MockClient);
+
+public:
+    void onePartInMultipartReceived(const ResourceResponse& response) override
+    {
+        m_responses.append(response);
+        m_data.append(Vector<char>());
+    }
+    void multipartDataReceived(const char* bytes, size_t size) override
+    {
+        m_data.last().append(bytes, size);
+    }
+
+    Vector<ResourceResponse> m_responses;
+    Vector<Vector<char>> m_data;
+};
+
+TEST(MultipartResponseTest, PushOverLine)
+{
+    struct {
+        const char* input;
+        const size_t position;
+        const size_t expected;
+    } lineTests[] = {
+        { "Line", 0, 0 },
+        { "Line", 2, 0 },
+        { "Line", 10, 0 },
+        { "\r\nLine", 0, 2 },
+        { "\nLine", 0, 1 },
+        { "\n\nLine", 0, 2 },
+        { "\rLine", 0, 1 },
+        { "Line\r\nLine", 4, 2 },
+        { "Line\nLine", 4, 1 },
+        { "Line\n\nLine", 4, 2 },
+        { "Line\rLine", 4, 1 },
+        { "Line\r\rLine", 4, 1 },
+    };
+    for (size_t i = 0; i < WTF_ARRAY_LENGTH(lineTests); ++i) {
+        Vector<char> input;
+        input.append(lineTests[i].input, strlen(lineTests[i].input));
+        EXPECT_EQ(lineTests[i].expected,
+            MultipartImageResourceParser::pushOverLineForTest(input, lineTests[i].position));
+    }
+}
+
+TEST(MultipartResponseTest, ParseMultipartHeadersResult)
+{
+    struct {
+        const char* data;
+        const bool result;
+        const size_t end;
+    } tests[] = {
+        { "This is junk", false, 0 },
+        { "Foo: bar\nBaz:\n\nAfter:\n", true, 15 },
+        { "Foo: bar\nBaz:\n", false, 0},
+        { "Foo: bar\r\nBaz:\r\n\r\nAfter:\r\n", true, 18 },
+        { "Foo: bar\r\nBaz:\r\n", false, 0 },
+        { "Foo: bar\nBaz:\r\n\r\nAfter:\n\n", true, 17 },
+        { "Foo: bar\r\nBaz:\n", false,  0 },
+        { "\r\n", true, 2 },
+    };
+    for (size_t i = 0; i < WTF_ARRAY_LENGTH(tests); ++i) {
+        WebURLResponse response;
+        response.initialize();
+        size_t end = 0;
+        bool result = Platform::current()->parseMultipartHeadersFromBody(tests[i].data, strlen(tests[i].data), &response, &end);
+        EXPECT_EQ(tests[i].result, result);
+        EXPECT_EQ(tests[i].end, end);
+    }
+}
+
+TEST(MultipartResponseTest, ParseMultipartHeaders)
+{
+    WebURLResponse webResponse;
+    webResponse.initialize();
+    webResponse.addHTTPHeaderField(WebString::fromLatin1("foo"), WebString::fromLatin1("bar"));
+    webResponse.addHTTPHeaderField(WebString::fromLatin1("range"), WebString::fromLatin1("piyo"));
+    webResponse.addHTTPHeaderField(WebString::fromLatin1("content-length"), WebString::fromLatin1("999"));
+
+    const char data[] = "content-type: image/png\ncontent-length: 10\n\n";
+    size_t end = 0;
+    bool result = Platform::current()->parseMultipartHeadersFromBody(data, strlen(data), &webResponse, &end);
+    const ResourceResponse& response = webResponse.toResourceResponse();
+
+    EXPECT_TRUE(result);
+    EXPECT_EQ(strlen(data), end);
+    EXPECT_EQ("image/png", response.httpHeaderField("content-type"));
+    EXPECT_EQ("10", response.httpHeaderField("content-length"));
+    EXPECT_EQ("bar", response.httpHeaderField("foo"));
+    EXPECT_EQ(AtomicString(), response.httpHeaderField("range"));
+}
+
+TEST(MultipartResponseTest, ParseMultipartHeadersContentCharset)
+{
+    WebURLResponse webResponse;
+    webResponse.initialize();
+
+    const char data[] = "content-type: text/html; charset=utf-8\n\n";
+    size_t end = 0;
+    bool result = Platform::current()->parseMultipartHeadersFromBody(data, strlen(data), &webResponse, &end);
+    const ResourceResponse& response = webResponse.toResourceResponse();
+
+    EXPECT_TRUE(result);
+    EXPECT_EQ(strlen(data), end);
+    EXPECT_EQ("text/html; charset=utf-8", response.httpHeaderField("content-type"));
+    EXPECT_EQ("utf-8", response.textEncodingName());
+}
+
+TEST(MultipartResponseTest, FindBoundary)
+{
+    struct {
+        const char* boundary;
+        const char* data;
+        const size_t position;
+    } boundaryTests[] = {
+        { "bound", "bound", 0 },
+        { "bound", "--bound", 0 },
+        { "bound", "junkbound", 4 },
+        { "bound", "junk--bound", 4 },
+        { "foo", "bound", kNotFound },
+        { "bound", "--boundbound", 0 },
+    };
+
+    for (size_t i = 0; i < WTF_ARRAY_LENGTH(boundaryTests); ++i) {
+        Vector<char> boundary, data;
+        boundary.append(boundaryTests[i].boundary, strlen(boundaryTests[i].boundary));
+        data.append(boundaryTests[i].data, strlen(boundaryTests[i].data));
+        EXPECT_EQ(boundaryTests[i].position, MultipartImageResourceParser::findBoundaryForTest(data, &boundary));
+    }
+}
+
+TEST(MultipartResponseTest, NoStartBoundary)
+{
+    ResourceResponse response;
+    response.setMimeType("multipart/x-mixed-replace");
+    response.setHTTPHeaderField("Foo", "Bar");
+    response.setHTTPHeaderField("Content-type", "text/plain");
+    MockClient* client = new MockClient;
+    Vector<char> boundary;
+    boundary.append("bound", 5);
+
+    MultipartImageResourceParser* parser = new MultipartImageResourceParser(response, boundary, client);
+    const char data[] =
+        "Content-type: text/plain\n\n"
+        "This is a sample response\n"
+        "--bound--"
+        "ignore junk after end token --bound\n\nTest2\n";
+    parser->appendData(data, strlen(data));
+    ASSERT_EQ(1u, client->m_responses.size());
+    ASSERT_EQ(1u, client->m_data.size());
+    EXPECT_EQ("This is a sample response", toString(client->m_data[0]));
+
+    parser->finish();
+    ASSERT_EQ(1u, client->m_responses.size());
+    ASSERT_EQ(1u, client->m_data.size());
+    EXPECT_EQ("This is a sample response", toString(client->m_data[0]));
+}
+
+TEST(MultipartResponseTest, NoEndBoundary)
+{
+    ResourceResponse response;
+    response.setMimeType("multipart/x-mixed-replace");
+    response.setHTTPHeaderField("Foo", "Bar");
+    response.setHTTPHeaderField("Content-type", "text/plain");
+    MockClient* client = new MockClient;
+    Vector<char> boundary;
+    boundary.append("bound", 5);
+
+    MultipartImageResourceParser* parser = new MultipartImageResourceParser(response, boundary, client);
+    const char data[] =
+        "bound\nContent-type: text/plain\n\n"
+        "This is a sample response\n";
+    parser->appendData(data, strlen(data));
+    ASSERT_EQ(1u, client->m_responses.size());
+    ASSERT_EQ(1u, client->m_data.size());
+    EXPECT_EQ("This is a sample response\n", toString(client->m_data[0]));
+
+    parser->finish();
+    ASSERT_EQ(1u, client->m_responses.size());
+    ASSERT_EQ(1u, client->m_data.size());
+    EXPECT_EQ("This is a sample response\n", toString(client->m_data[0]));
+}
+
+TEST(MultipartResponseTest, NoStartAndEndBoundary)
+{
+    ResourceResponse response;
+    response.setMimeType("multipart/x-mixed-replace");
+    response.setHTTPHeaderField("Foo", "Bar");
+    response.setHTTPHeaderField("Content-type", "text/plain");
+    MockClient* client = new MockClient;
+    Vector<char> boundary;
+    boundary.append("bound", 5);
+
+    MultipartImageResourceParser* parser = new MultipartImageResourceParser(response, boundary, client);
+    const char data[] =
+        "Content-type: text/plain\n\n"
+        "This is a sample response\n";
+    parser->appendData(data, strlen(data));
+    ASSERT_EQ(1u, client->m_responses.size());
+    ASSERT_EQ(1u, client->m_data.size());
+    EXPECT_EQ("This is a sample response\n", toString(client->m_data[0]));
+
+    parser->finish();
+    ASSERT_EQ(1u, client->m_responses.size());
+    ASSERT_EQ(1u, client->m_data.size());
+    EXPECT_EQ("This is a sample response\n", toString(client->m_data[0]));
+}
+
+TEST(MultipartResponseTest, MalformedBoundary)
+{
+    // Some servers send a boundary that is prefixed by "--".  See bug 5786.
+    ResourceResponse response;
+    response.setMimeType("multipart/x-mixed-replace");
+    response.setHTTPHeaderField("Foo", "Bar");
+    response.setHTTPHeaderField("Content-type", "text/plain");
+    MockClient* client = new MockClient;
+    Vector<char> boundary;
+    boundary.append("--bound", 7);
+
+    MultipartImageResourceParser* parser = new MultipartImageResourceParser(response, boundary, client);
+    const char data[] =
+        "--bound\n"
+        "Content-type: text/plain\n\n"
+        "This is a sample response\n"
+        "--bound--"
+        "ignore junk after end token --bound\n\nTest2\n";
+    parser->appendData(data, strlen(data));
+    ASSERT_EQ(1u, client->m_responses.size());
+    ASSERT_EQ(1u, client->m_data.size());
+    EXPECT_EQ("This is a sample response", toString(client->m_data[0]));
+
+    parser->finish();
+    ASSERT_EQ(1u, client->m_responses.size());
+    ASSERT_EQ(1u, client->m_data.size());
+    EXPECT_EQ("This is a sample response", toString(client->m_data[0]));
+}
+
+// Used in for tests that break the data in various places.
+struct TestChunk {
+    const int startPosition; // offset in data
+    const int endPosition; // end offset in data
+    const size_t expectedResponses;
+    const char* expectedData;
+};
+
+void variousChunkSizesTest(const TestChunk chunks[], int chunksSize,
+    size_t responses, int receivedData,
+    const char* completedData)
+{
+    const char data[] =
+        "--bound\n" // 0-7
+        "Content-type: image/png\n\n" // 8-32
+        "datadatadatadatadata" // 33-52
+        "--bound\n" // 53-60
+        "Content-type: image/jpg\n\n" // 61-85
+        "foofoofoofoofoo" // 86-100
+        "--bound--"; // 101-109
+
+    ResourceResponse response;
+    response.setMimeType("multipart/x-mixed-replace");
+    MockClient* client = new MockClient;
+    Vector<char> boundary;
+    boundary.append("bound", 5);
+
+    MultipartImageResourceParser* parser = new MultipartImageResourceParser(response, boundary, client);
+
+    for (int i = 0; i < chunksSize; ++i) {
+        ASSERT_LT(chunks[i].startPosition, chunks[i].endPosition);
+        parser->appendData(data + chunks[i].startPosition, chunks[i].endPosition - chunks[i].startPosition);
+        EXPECT_EQ(chunks[i].expectedResponses, client->m_responses.size());
+        EXPECT_EQ(String(chunks[i].expectedData), client->m_data.size() > 0 ? toString(client->m_data.last()) : String(""));
+    }
+    // Check final state
+    parser->finish();
+    EXPECT_EQ(responses, client->m_responses.size());
+    EXPECT_EQ(completedData, toString(client->m_data.last()));
+}
+
+template <size_t N>
+void variousChunkSizesTest(const TestChunk (&chunks)[N], size_t responses, int receivedData, const char* completedData)
+{
+    variousChunkSizesTest(chunks, N, responses, receivedData, completedData);
+}
+
+TEST(MultipartResponseTest, BreakInBoundary)
+{
+    // Break in the first boundary
+    const TestChunk bound1[] = {
+        { 0, 4, 0, "" },
+        { 4, 110, 2, "foofoofoofoofoo" },
+    };
+    variousChunkSizesTest(bound1, 2, 2, "foofoofoofoofoo");
+
+    // Break in first and second
+    const TestChunk bound2[] = {
+        { 0, 4, 0, "" },
+        { 4, 55, 1, "datadatadatadat" },
+        { 55, 65, 1, "datadatadatadatadata" },
+        { 65, 110, 2, "foofoofoofoofoo" },
+    };
+    variousChunkSizesTest(bound2, 2, 3, "foofoofoofoofoo");
+
+    // Break in second only
+    const TestChunk bound3[] = {
+        { 0, 55, 1, "datadatadatadat" },
+        { 55, 110, 2, "foofoofoofoofoo" },
+    };
+    variousChunkSizesTest(bound3, 2, 3, "foofoofoofoofoo");
+}
+
+TEST(MultipartResponseTest, BreakInHeaders)
+{
+    // Break in first header
+    const TestChunk header1[] = {
+        { 0, 10, 0, "" },
+        { 10, 35, 1, "" },
+        { 35, 110, 2, "foofoofoofoofoo" },
+    };
+    variousChunkSizesTest(header1, 2, 2, "foofoofoofoofoo");
+
+    // Break in both headers
+    const TestChunk header2[] = {
+        { 0, 10, 0, "" },
+        { 10, 65, 1, "datadatadatadatadata" },
+        { 65, 110, 2, "foofoofoofoofoo" },
+    };
+    variousChunkSizesTest(header2, 2, 2, "foofoofoofoofoo");
+
+    // Break at end of a header
+    const TestChunk header3[] = {
+        { 0, 33, 1, "" },
+        { 33, 65, 1, "datadatadatadatadata" },
+        { 65, 110, 2, "foofoofoofoofoo" },
+    };
+    variousChunkSizesTest(header3, 2, 2, "foofoofoofoofoo");
+}
+
+TEST(MultipartResponseTest, BreakInData)
+{
+    // All data as one chunk
+    const TestChunk data1[] = {
+        { 0, 110, 2, "foofoofoofoofoo" },
+    };
+    variousChunkSizesTest(data1, 2, 2, "foofoofoofoofoo");
+
+    // breaks in data segment
+    const TestChunk data2[] = {
+        { 0, 35, 1, "" },
+        { 35, 65, 1, "datadatadatadatadata" },
+        { 65, 90, 2, "" },
+        { 90, 110, 2, "foofoofoofoofoo" },
+    };
+    variousChunkSizesTest(data2, 2, 2, "foofoofoofoofoo");
+
+    // Incomplete send
+    const TestChunk data3[] = {
+        { 0, 35, 1, "" },
+        { 35, 90, 2, "" },
+    };
+    variousChunkSizesTest(data3, 2, 2, "foof");
+}
+
+TEST(MultipartResponseTest, SmallChunk)
+{
+    ResourceResponse response;
+    response.setMimeType("multipart/x-mixed-replace");
+    response.setHTTPHeaderField("Content-type", "text/plain");
+    MockClient* client = new MockClient;
+    Vector<char> boundary;
+    boundary.append("bound", 5);
+
+    MultipartImageResourceParser* parser = new MultipartImageResourceParser(response, boundary, client);
+
+    // Test chunks of size 1, 2, and 0.
+    const char data[] =
+        "--boundContent-type: text/plain\n\n"
+        "\n--boundContent-type: text/plain\n\n"
+        "\n\n--boundContent-type: text/plain\n\n"
+        "--boundContent-type: text/plain\n\n"
+        "end--bound--";
+    parser->appendData(data, strlen(data));
+    ASSERT_EQ(4u, client->m_responses.size());
+    ASSERT_EQ(4u, client->m_data.size());
+    EXPECT_EQ("", toString(client->m_data[0]));
+    EXPECT_EQ("\n", toString(client->m_data[1]));
+    EXPECT_EQ("", toString(client->m_data[2]));
+    EXPECT_EQ("end", toString(client->m_data[3]));
+
+    parser->finish();
+    ASSERT_EQ(4u, client->m_responses.size());
+    ASSERT_EQ(4u, client->m_data.size());
+    EXPECT_EQ("", toString(client->m_data[0]));
+    EXPECT_EQ("\n", toString(client->m_data[1]));
+    EXPECT_EQ("", toString(client->m_data[2]));
+    EXPECT_EQ("end", toString(client->m_data[3]));
+}
+
+TEST(MultipartResponseTest, MultipleBoundaries)
+{
+    // Test multiple boundaries back to back
+    ResourceResponse response;
+    response.setMimeType("multipart/x-mixed-replace");
+    MockClient* client = new MockClient;
+    Vector<char> boundary;
+    boundary.append("bound", 5);
+
+    MultipartImageResourceParser* parser = new MultipartImageResourceParser(response, boundary, client);
+
+    const char data[] = "--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--";
+    parser->appendData(data, strlen(data));
+    ASSERT_EQ(2u, client->m_responses.size());
+    ASSERT_EQ(2u, client->m_data.size());
+    EXPECT_EQ("", toString(client->m_data[0]));
+    EXPECT_EQ("foofoo", toString(client->m_data[1]));
+}
+
+TEST(MultipartResponseTest, MultipartPayloadSet)
+{
+    ResourceResponse response;
+    response.setMimeType("multipart/x-mixed-replace");
+    MockClient* client = new MockClient;
+    Vector<char> boundary;
+    boundary.append("bound", 5);
+
+    MultipartImageResourceParser* parser = new MultipartImageResourceParser(response, boundary, client);
+
+    const char data[] =
+        "--bound\n"
+        "Content-type: text/plain\n\n"
+        "response data\n"
+        "--bound\n";
+    parser->appendData(data, strlen(data));
+    ASSERT_EQ(1u, client->m_responses.size());
+    ASSERT_EQ(1u, client->m_data.size());
+    EXPECT_EQ("response data", toString(client->m_data[0]));
+    EXPECT_FALSE(client->m_responses[0].isMultipartPayload());
+
+    const char data2[] =
+        "Content-type: text/plain\n\n"
+        "response data2\n"
+        "--bound\n";
+    parser->appendData(data2, strlen(data2));
+    ASSERT_EQ(2u, client->m_responses.size());
+    ASSERT_EQ(2u, client->m_data.size());
+    EXPECT_EQ("response data2", toString(client->m_data[1]));
+    EXPECT_TRUE(client->m_responses[1].isMultipartPayload());
+}
+
+} // namespace
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
index 1834568f..c0864494 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -440,6 +440,7 @@
 
     updateMemoryCacheStats(resource.get(), policy, request, factory, isStaticData);
 
+    initializeResourceRequest(request.mutableResourceRequest(), factory.type());
     switch (policy) {
     case Reload:
         memoryCache()->remove(resource.get());
@@ -592,7 +593,6 @@
 
     WTF_LOG(ResourceLoading, "Loading Resource for '%s'.", request.resourceRequest().url().elidedString().latin1().data());
 
-    initializeResourceRequest(request.mutableResourceRequest(), factory.type());
     RefPtrWillBeRawPtr<Resource> resource = factory.create(request.resourceRequest(), charset);
     resource->setLinkPreload(request.isLinkPreload());
     resource->setCacheIdentifier(cacheIdentifier);
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 5973ff2..7725566 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -250,12 +250,6 @@
     }
 }
 
-void FrameView::removeFromAXObjectCache()
-{
-    if (AXObjectCache* cache = axObjectCache())
-        cache->childrenChanged(m_frame->pagePopupOwner());
-}
-
 void FrameView::init()
 {
     reset();
@@ -277,10 +271,6 @@
 
     detachScrollbars();
 
-    // When the view is no longer associated with a frame, it needs to be removed from the ax object cache
-    // right now, otherwise it won't be able to reach the topDocument()'s axObject cache later.
-    removeFromAXObjectCache();
-
     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
         scrollingCoordinator->willDestroyScrollableArea(this);
 
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h
index ec6bf30..f17b7c5 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -723,7 +723,6 @@
     void updateScrollCorner();
 
     AXObjectCache* axObjectCache() const;
-    void removeFromAXObjectCache();
 
     void setLayoutSizeInternal(const IntSize&);
 
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
index a88b065f..8028a4f 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -388,15 +388,6 @@
     return m_script->getWindowProxyManager();
 }
 
-void LocalFrame::disconnectOwnerElement()
-{
-    if (owner()) {
-        if (Document* document = this->document())
-            document->topDocument().clearAXObjectCache();
-    }
-    Frame::disconnectOwnerElement();
-}
-
 bool LocalFrame::shouldClose()
 {
     // TODO(dcheng): This should be fixed to dispatch beforeunload events to
@@ -781,7 +772,7 @@
     FloatSize remainingDelta = delta;
 
     // If this is main frame, allow top controls to scroll first.
-    if (shouldScrollTopControls(delta))
+    if (shouldScrollTopControls(granularity, delta))
         remainingDelta = host()->topControls().scrollBy(remainingDelta);
 
     if (remainingDelta.isZero())
@@ -794,11 +785,14 @@
     return result;
 }
 
-bool LocalFrame::shouldScrollTopControls(const FloatSize& delta) const
+bool LocalFrame::shouldScrollTopControls(ScrollGranularity granularity, const FloatSize& delta) const
 {
     if (!isMainFrame())
         return false;
 
+    if (granularity != ScrollByPixel && granularity != ScrollByPrecisePixel)
+        return false;
+
     // Always give the delta to the top controls if the scroll is in
     // the direction to show the top controls. If it's in the
     // direction to hide the top controls, only give the delta to the
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.h b/third_party/WebKit/Source/core/frame/LocalFrame.h
index f2680cf8..54921de 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.h
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.h
@@ -97,7 +97,6 @@
     void navigate(const FrameLoadRequest&) override;
     void reload(FrameLoadType, ClientRedirectPolicy) override;
     void detach(FrameDetachType) override;
-    void disconnectOwnerElement() override;
     bool shouldClose() override;
     SecurityContext* securityContext() const override;
     void printNavigationErrorMessage(const Frame&, const char* reason) override;
@@ -193,7 +192,7 @@
 
     LocalFrame(FrameLoaderClient*, FrameHost*, FrameOwner*);
 
-    bool shouldScrollTopControls(const FloatSize& delta) const;
+    bool shouldScrollTopControls(ScrollGranularity, const FloatSize& delta) const;
 
     // Internal Frame helper overrides:
     WindowProxyManager* getWindowProxyManager() const override;
diff --git a/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp b/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
index 0e86879..953a6ce 100644
--- a/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
@@ -84,10 +84,9 @@
     // tree can change inertness which means they must be added or removed from
     // the tree. The most foolproof way is to clear the entire tree and rebuild
     // it, though a more clever way is probably possible.
-    Document& topDocument = document.topDocument();
-    topDocument.clearAXObjectCache();
-    if (AXObjectCache* cache = topDocument.axObjectCache())
-        cache->childrenChanged(&topDocument);
+    document.clearAXObjectCache();
+    if (AXObjectCache* cache = document.axObjectCache())
+        cache->childrenChanged(&document);
 }
 
 inline HTMLDialogElement::HTMLDialogElement(Document& document)
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index 843fe17..6e71b91 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -3716,6 +3716,17 @@
 
 void HTMLMediaElement::rejectPlayPromises(ExceptionCode code, const String& message)
 {
+    // TODO(mlamouri): band-aid to fix a crash where inserting a <source> will
+    // resolve the promise in the same stack as the <source> insertion. The
+    // underlying cause is that when <source> is inserted, the implementation
+    // is running the loading algorithm instead of the resource selection
+    // algorithm. See https://crbug.com/590634.
+    if (ScriptForbiddenScope::isScriptForbidden()) {
+        if (!m_playResolvers.isEmpty())
+            scheduleRejectPlayPromises(code);
+        return;
+    }
+
     ASSERT(code == AbortError || code == NotSupportedError);
 
     for (auto& resolver: m_playResolvers)
diff --git a/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp b/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
index 3cb4c6e..7d1782c 100644
--- a/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
@@ -273,6 +273,19 @@
 
 void HTMLTextAreaElement::subtreeHasChanged()
 {
+#if ENABLE(ASSERT)
+    // The innerEditor should have either Text nodes or a placeholder break
+    // element. If we see other nodes, it's a bug in editing code and we should
+    // fix it.
+    Element* innerEditor = innerEditorElement();
+    for (Node& node : NodeTraversal::descendantsOf(*innerEditor)) {
+        if (node.isTextNode())
+            continue;
+        ASSERT(isHTMLBRElement(node));
+        ASSERT(&node == innerEditor->lastChild());
+    }
+#endif
+    addPlaceholderBreakElementIfNecessary();
     setChangedSinceLastFormControlChangeEvent(true);
     m_valueIsUpToDate = false;
     setNeedsValidityCheck();
diff --git a/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp b/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp
index 9d23449..148395b 100644
--- a/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp
@@ -620,6 +620,23 @@
     return m_lastChangeWasUserEdit;
 }
 
+PassRefPtrWillBeRawPtr<Node> HTMLTextFormControlElement::createPlaceholderBreakElement() const
+{
+    return HTMLBRElement::create(document());
+}
+
+void HTMLTextFormControlElement::addPlaceholderBreakElementIfNecessary()
+{
+    HTMLElement* innerEditor = innerEditorElement();
+    if (innerEditor->layoutObject() && !innerEditor->layoutObject()->style()->preserveNewline())
+        return;
+    Node* lastChild = innerEditor->lastChild();
+    if (!lastChild || !lastChild->isTextNode())
+        return;
+    if (toText(lastChild)->data().endsWith('\n') || toText(lastChild)->data().endsWith('\r'))
+        innerEditor->appendChild(createPlaceholderBreakElement());
+}
+
 void HTMLTextFormControlElement::setInnerEditorValue(const String& value)
 {
     ASSERT(!openShadowRoot());
@@ -642,8 +659,9 @@
     else
         replaceChildrenWithText(innerEditor, value, ASSERT_NO_EXCEPTION);
 
-    if (value.endsWith('\n') || value.endsWith('\r'))
-        innerEditor->appendChild(HTMLBRElement::create(document()));
+    // Add <br> so that we can put the caret at the next line of the last
+    // newline.
+    addPlaceholderBreakElementIfNecessary();
 
     if (textIsChanged && layoutObject()) {
         if (AXObjectCache* cache = document().existingAXObjectCache())
@@ -651,15 +669,6 @@
     }
 }
 
-static String finishText(StringBuilder& result)
-{
-    // Remove one trailing newline; there's always one that's collapsed out by layoutObject.
-    size_t size = result.length();
-    if (size && result[size - 1] == '\n')
-        result.resize(--size);
-    return result.toString();
-}
-
 String HTMLTextFormControlElement::innerEditorValue() const
 {
     ASSERT(!openShadowRoot());
@@ -669,12 +678,15 @@
 
     StringBuilder result;
     for (Node& node : NodeTraversal::inclusiveDescendantsOf(*innerEditor)) {
-        if (isHTMLBRElement(node))
-            result.append(newlineCharacter);
-        else if (node.isTextNode())
+        if (isHTMLBRElement(node)) {
+            ASSERT(&node == innerEditor->lastChild());
+            if (&node != innerEditor->lastChild())
+                result.append(newlineCharacter);
+        } else if (node.isTextNode()) {
             result.append(toText(node).data());
+        }
     }
-    return finishText(result);
+    return result.toString();
 }
 
 static void getNextSoftBreak(RootInlineBox*& line, Node*& breakNode, unsigned& breakOffset)
@@ -717,7 +729,9 @@
     StringBuilder result;
     for (Node& node : NodeTraversal::descendantsOf(*innerText)) {
         if (isHTMLBRElement(node)) {
-            result.append(newlineCharacter);
+            ASSERT(&node == innerText->lastChild());
+            if (&node != innerText->lastChild())
+                result.append(newlineCharacter);
         } else if (node.isTextNode()) {
             String data = toText(node).data();
             unsigned length = data.length();
@@ -735,7 +749,7 @@
         while (breakNode == node)
             getNextSoftBreak(line, breakNode, breakOffset);
     }
-    return finishText(result);
+    return result.toString();
 }
 
 HTMLTextFormControlElement* enclosingTextFormControl(const Position& position)
diff --git a/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h b/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h
index e032959d..38627890 100644
--- a/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h
@@ -97,6 +97,7 @@
     bool lastChangeWasUserEdit() const;
     virtual void setInnerEditorValue(const String&);
     String innerEditorValue() const;
+    PassRefPtrWillBeRawPtr<Node> createPlaceholderBreakElement() const;
 
     String directionForFormData() const;
 
@@ -131,7 +132,7 @@
     virtual void subtreeHasChanged() = 0;
 
     void setLastChangeWasNotUserEdit() { m_lastChangeWasUserEdit = false; }
-
+    void addPlaceholderBreakElementIfNecessary();
     String valueWithHardLineBreaks() const;
 
     virtual bool shouldDispatchFormControlChangeEvent(String&, String&);
diff --git a/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp b/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
index 63c40441..abe4838 100644
--- a/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
+++ b/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
@@ -99,7 +99,7 @@
         // Need to put something to keep text baseline.
         displayValue = " ";
     }
-    toHTMLElement(node)->setInnerText(displayValue, ASSERT_NO_EXCEPTION);
+    toHTMLElement(node)->setTextContent(displayValue);
 }
 
 void BaseChooserOnlyDateAndTimeInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior)
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
index e78e237e..4e619ec 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
@@ -34,6 +34,7 @@
 #include "core/html/HTMLMediaElement.h"
 #include "core/html/track/TextTrackContainer.h"
 #include "core/layout/LayoutTheme.h"
+#include "platform/EventDispatchForbiddenScope.h"
 
 namespace blink {
 
@@ -231,13 +232,14 @@
 
 void MediaControls::reset()
 {
+    EventDispatchForbiddenScope::AllowUserAgentEvents allowEventsInShadow;
     const bool useNewUi = RuntimeEnabledFeatures::newMediaPlaybackUiEnabled();
     BatchedControlUpdate batch(this);
 
     m_allowHiddenVolumeControls = useNewUi;
 
     const double duration = mediaElement().duration();
-    m_durationDisplay->setInnerText(LayoutTheme::theme().formatMediaControlsTime(duration), ASSERT_NO_EXCEPTION);
+    m_durationDisplay->setTextContent(LayoutTheme::theme().formatMediaControlsTime(duration));
     m_durationDisplay->setCurrentValue(duration);
 
     if (useNewUi) {
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 6dd5400..570f5228 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -600,8 +600,10 @@
         controller->stopAutoscroll();
 }
 
-ScrollResult EventHandler::physicalScroll(ScrollGranularity granularity, const FloatSize& delta, Node* startNode, Node** stopNode)
+ScrollResult EventHandler::physicalScroll(ScrollGranularity granularity, const FloatSize& delta, Node* startNode, Node** stopNode, bool* consumed)
 {
+    if (consumed)
+        *consumed = false;
     if (delta.isZero())
         return ScrollResult();
 
@@ -613,7 +615,7 @@
     ScrollResult result;
 
     LayoutBox* curBox = node->layoutObject()->enclosingBox();
-    while (curBox && !curBox->isLayoutView()) {
+    while (curBox) {
         // If we're at the stopNode, we should try to scroll it but we shouldn't
         // chain past it.
         bool shouldStopChaining =
@@ -625,12 +627,8 @@
 
         if (result.didScroll() || shouldStopChaining) {
             setFrameWasScrolledByUser();
-            if (!result.didScroll()) {
-                // TODO(bokan): We should probably add a "shouldPropagate" bit
-                // on the result rather than lying to the caller.
-                result.didScrollX = true;
-                result.didScrollY = true;
-            }
+            if (consumed)
+                *consumed = true;
             return result;
         }
 
@@ -651,12 +649,12 @@
         node = m_mousePressNode.get();
 
     if (!node || !node->layoutObject())
-        return false;
+        node = m_frame->view()->layoutView()->node();
 
     m_frame->document()->updateLayoutIgnorePendingStylesheets();
 
     LayoutBox* curBox = node->layoutObject()->enclosingBox();
-    while (curBox && !curBox->isLayoutView()) {
+    while (curBox) {
         ScrollDirectionPhysical physicalDirection = toPhysicalDirection(
             direction, curBox->isHorizontalWritingMode(), curBox->style()->isFlippedBlocksWritingMode());
 
@@ -698,18 +696,8 @@
     // FIXME: enable scroll customization in this case. See crbug.com/410974.
     if (logicalScroll(direction, granularity, startingNode))
         return true;
-    LocalFrame* frame = m_frame;
-    FrameView* view = frame->view();
-    if (view) {
-        ScrollDirectionPhysical physicalDirection =
-            toPhysicalDirection(direction, view->isVerticalDocument(), view->isFlippedDocument());
-        if (view->scrollableArea()->userScroll(granularity, toScrollDelta(physicalDirection, 1)).didScroll()) {
-            setFrameWasScrolledByUser();
-            return true;
-        }
-    }
 
-    Frame* parentFrame = frame->tree().parent();
+    Frame* parentFrame = m_frame->tree().parent();
     if (!parentFrame || !parentFrame->isLocalFrame())
         return false;
     // FIXME: Broken for OOPI.
@@ -1784,35 +1772,6 @@
     return false;
 }
 
-namespace {
-
-ScrollResult scrollAreaWithWheelEvent(const PlatformWheelEvent& event, ScrollableArea& scrollableArea)
-{
-    float deltaX = event.getRailsMode() != PlatformEvent::RailsModeVertical ? event.deltaX() : 0;
-    float deltaY = event.getRailsMode() != PlatformEvent::RailsModeHorizontal ? event.deltaY() : 0;
-
-    ScrollGranularity granularity =
-        event.granularity() == ScrollByPixelWheelEvent ? ScrollByPixel : ScrollByPage;
-
-    if (event.hasPreciseScrollingDeltas() && granularity == ScrollByPixel)
-        granularity = ScrollByPrecisePixel;
-
-    // If the event is a "PageWheelEvent" we should disregard the delta and
-    // scroll by *one* page length per event.
-    if (event.granularity() == ScrollByPageWheelEvent) {
-        if (deltaX)
-            deltaX = deltaX > 0 ? 1 : -1;
-        if (deltaY)
-            deltaY = deltaY > 0 ? 1 : -1;
-    }
-
-    // On a wheel event, positive delta is meant to scroll up and left, which
-    // is the opposite of deltas in the scrolling system.
-    return scrollableArea.userScroll(granularity, FloatSize(-deltaX, -deltaY));
-}
-
-} // namespace
-
 WebInputEventResult EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
 {
     Document* doc = m_frame->document();
@@ -1853,33 +1812,19 @@
         sendDOMEvent = false;
     }
 
-    if (node && sendDOMEvent) {
-        RefPtrWillBeRawPtr<Event> domEvent = WheelEvent::create(event, node->document().domWindow());
-        DispatchEventResult domEventResult = node->dispatchEvent(domEvent);
-        if (domEventResult != DispatchEventResult::NotCanceled) {
-            setFrameWasScrolledByUser();
-            return toWebInputEventResult(domEventResult);
+    if (node) {
+        RefPtrWillBeRawPtr<WheelEvent> domEvent = WheelEvent::create(event, node->document().domWindow());
+        if (sendDOMEvent) {
+            DispatchEventResult domEventResult = node->dispatchEvent(domEvent);
+            if (domEventResult != DispatchEventResult::NotCanceled)
+                return toWebInputEventResult(domEventResult);
+        } else {
+            defaultWheelEventHandler(node, domEvent.get());
+            if (domEvent->defaultHandled())
+                return WebInputEventResult::HandledSystem;
         }
     }
 
-    // We do another check on the frame view because the event handler can run
-    // JS which results in the frame getting destroyed.
-    view = m_frame->view();
-    if (!view)
-        return WebInputEventResult::NotHandled;
-
-    // Wheel events which do not scroll are used to trigger zooming.
-    if (!event.canScroll())
-        return WebInputEventResult::NotHandled;
-
-    ScrollResult scrollResult = scrollAreaWithWheelEvent(event, *view->scrollableArea());
-    if (m_frame->isMainFrame() && m_frame->settings() && m_frame->settings()->reportWheelOverscroll())
-        handleOverscroll(scrollResult);
-    if (scrollResult.didScroll()) {
-        setFrameWasScrolledByUser();
-        return WebInputEventResult::HandledSystem;
-    }
-
     return WebInputEventResult::NotHandled;
 }
 
@@ -1905,11 +1850,25 @@
     if (wheelEvent->getRailsMode() != Event::RailsModeHorizontal)
         delta.setHeight(wheelEvent->deltaY());
 
-    // FIXME: enable scroll customization in this case. See crbug.com/410974.
-    ScrollResult result = physicalScroll(granularity, delta, startNode, &node);
+    // We can get page wheel events with non-[0|1] deltas in the case where the
+    // events are coalesced but we still want to scroll by just one page length.
+    // TODO(bokan): This seems like it belongs in the coalescing logic.
+    if (granularity == ScrollByPage) {
+        if (delta.width())
+            delta.setWidth(delta.width() > 0 ? 1 : -1);
+        if (delta.height())
+            delta.setHeight(delta.height() > 0 ? 1 : -1);
+    }
 
-    if (result.didScroll())
+    // FIXME: enable scroll customization in this case. See crbug.com/410974.
+    bool consumed = false;
+    ScrollResult result = physicalScroll(granularity, delta, startNode, &node, &consumed);
+
+    if (consumed)
         wheelEvent->setDefaultHandled();
+
+    if (m_frame->isMainFrame() && m_frame->settings() && m_frame->settings()->reportWheelOverscroll())
+        handleOverscroll(result);
 }
 
 WebInputEventResult EventHandler::handleGestureShowPress()
@@ -2437,7 +2396,6 @@
             return result;
         }
 
-        bool scrolled = false;
         if (handleScrollCustomization) {
             OwnPtr<ScrollStateData> scrollStateData = adoptPtr(new ScrollStateData());
             scrollStateData->delta_x = delta.width();
@@ -2460,40 +2418,32 @@
             customizedScroll(*node, *scrollState);
             m_previousGestureScrolledNode = scrollState->currentNativeScrollingElement();
             m_deltaConsumedForScrollSequence = scrollState->deltaConsumedForScrollSequence();
-            scrolled = scrollState->deltaX() != delta.width()
-                || scrollState->deltaY() != delta.height();
+            if (scrollState->deltaX() != delta.width()
+                || scrollState->deltaY() != delta.height()) {
+                setFrameWasScrolledByUser();
+                return WebInputEventResult::HandledSystem;
+            }
         } else {
             Node* stopNode = nullptr;
             if (gestureEvent.preventPropagation())
                 stopNode = m_previousGestureScrolledNode.get();
 
-            ScrollResult result = physicalScroll(granularity, delta, node, &stopNode);
-
-            scrolled = result.didScroll();
+            bool consumed = false;
+            ScrollResult result = physicalScroll(granularity, delta, node, &stopNode, &consumed);
 
             if (gestureEvent.preventPropagation())
                 m_previousGestureScrolledNode = stopNode;
 
-            resetOverscroll(result.didScrollX, result.didScrollY);
-        }
-        if (scrolled) {
-            setFrameWasScrolledByUser();
-            return WebInputEventResult::HandledSystem;
-        }
-    }
+            if (m_frame->isMainFrame() && (!stopNode || stopNode->layoutObject() == m_frame->view()->layoutView())) {
+                FloatPoint position = FloatPoint(gestureEvent.position().x(), gestureEvent.position().y());
+                handleOverscroll(result, position, velocity);
+            } else {
+                resetOverscroll(result.didScrollX, result.didScrollY);
+            }
 
-    if (handleScrollCustomization)
-        return WebInputEventResult::NotHandled;
-
-    // Try to scroll the frame view.
-    ScrollResult scrollResult = m_frame->applyScrollDelta(granularity, delta, false);
-    if (m_frame->isMainFrame()) {
-        FloatPoint position = FloatPoint(gestureEvent.position().x(), gestureEvent.position().y());
-        handleOverscroll(scrollResult, position, velocity);
-    }
-    if (scrollResult.didScroll()) {
-        setFrameWasScrolledByUser();
-        return WebInputEventResult::HandledSystem;
+            if (consumed)
+                return WebInputEventResult::HandledSystem;
+        }
     }
 
     return WebInputEventResult::NotHandled;
@@ -3455,16 +3405,6 @@
         event->setDefaultHandled();
         return;
     }
-
-    FrameView* view = m_frame->view();
-    if (!view)
-        return;
-
-    ScrollDirectionPhysical physicalDirection =
-        toPhysicalDirection(direction, view->isVerticalDocument(), view->isFlippedDocument());
-
-    if (view->scrollableArea()->userScroll(ScrollByPage, toScrollDelta(physicalDirection, 1)).didScroll())
-        event->setDefaultHandled();
 }
 
 void EventHandler::defaultBackspaceEventHandler(KeyboardEvent* event)
diff --git a/third_party/WebKit/Source/core/input/EventHandler.h b/third_party/WebKit/Source/core/input/EventHandler.h
index 276d2ded..a95cedbf 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.h
+++ b/third_party/WebKit/Source/core/input/EventHandler.h
@@ -273,21 +273,24 @@
     ScrollableArea* associatedScrollableArea(const PaintLayer*) const;
 
     // Performs a chaining scroll, within a *single* frame, starting from a
-    // given node and optionally stopping on a given node. Does *not* attempt
-    // to scroll the layout view.
+    // given node and optionally stopping on a given node.
     // granularity - The units that the  scroll delta parameter is in.
     // delta - The delta to scroll by, in the units of the granularity param
     //         (e.g. pixels, lines, pages, etc.). These are in a physical
     //         direction. i.e. Positive is down and right.
     // startNode - The node to start the scroll chaining from.
-    // stopNode - On input, if provided and non-null, the node at which we
-    //            should stop chaining. On output, if provided and a node was
-    //            scrolled, stopNode will point to that node.
-    ScrollResult physicalScroll(ScrollGranularity, const FloatSize& delta, Node* startNode, Node** stopNode = nullptr);
+    // stopNode - On input, if non-null, the node at which we should stop
+    //            chaining. On output, if provided and a node was scrolled,
+    //            stopNode will point to that node.
+    // consumed - [OUT] Whether the scroll was consumed. This is different than
+    //            ScrollResult.didScroll since we might not have scrolled but
+    //            have reached the stopNode and thus don't want to continue
+    //            chaining the scroll.
+    ScrollResult physicalScroll(ScrollGranularity, const FloatSize& delta, Node* startNode, Node** stopNode, bool* consumed);
 
     // Performs a chaining logical scroll, within a *single* frame, starting
     // from either a provided starting node or a default based on the focused or
-    // most recently clicked node.
+    // most recently clicked node, falling back to the frame.
     // Returns true if the scroll was consumed.
     // direction - The logical direction to scroll in. This will be converted to
     //             a physical direction for each LayoutBox we try to scroll
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index 40d50f0..d58373e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -721,36 +721,18 @@
         LayoutBlockFlow* nextBlock = toLayoutBlockFlow(next);
         LayoutBlockFlow* prevBlock = toLayoutBlockFlow(prev);
 
-        if (prev->childrenInline() != next->childrenInline()) {
-            LayoutBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
-            LayoutBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
+        // If the inlineness of children of the two block don't match, we'd need special code here
+        // (but there should be no need for it).
+        ASSERT(nextBlock->childrenInline() == prevBlock->childrenInline());
 
-            // Place the inline children block inside of the block children block instead of deleting it.
-            ASSERT(!inlineChildrenBlock->continuation());
-            bool inlineChildrenBlockHasLayer = inlineChildrenBlock->hasLayer();
-            children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlockHasLayer);
+        // Take all the children out of the |next| block and put them in
+        // the |prev| block.
+        nextBlock->moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
 
-            // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
-            blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
-                inlineChildrenBlockHasLayer || blockChildrenBlock->hasLayer());
-            next->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInvalidationReason::AnonymousBlockChange);
-
-            // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
-            // of "this". we null out prev or next so that is not used later in the function.
-            if (inlineChildrenBlock == prevBlock)
-                prev = nullptr;
-            else
-                next = nullptr;
-        } else {
-            // Take all the children out of the |next| block and put them in
-            // the |prev| block.
-            nextBlock->moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
-
-            // Delete the now-empty block's lines and nuke it.
-            nextBlock->deleteLineBoxTree();
-            nextBlock->destroy();
-            next = nullptr;
-        }
+        // Delete the now-empty block's lines and nuke it.
+        nextBlock->deleteLineBoxTree();
+        nextBlock->destroy();
+        next = nullptr;
     }
 
     LayoutBox::removeChild(oldChild);
diff --git a/third_party/WebKit/Source/core/layout/LayoutView.cpp b/third_party/WebKit/Source/core/layout/LayoutView.cpp
index b03b5ea..318317a 100644
--- a/third_party/WebKit/Source/core/layout/LayoutView.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutView.cpp
@@ -1025,4 +1025,12 @@
     return document().settings() && document().settings()->rootLayerScrolls();
 }
 
+ScrollResult LayoutView::scroll(ScrollGranularity granularity, const FloatSize& delta)
+{
+    if (!frameView())
+        return ScrollResult();
+
+    return frame()->applyScrollDelta(granularity, delta, false);
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutView.h b/third_party/WebKit/Source/core/layout/LayoutView.h
index d243fa5b..256cc007 100644
--- a/third_party/WebKit/Source/core/layout/LayoutView.h
+++ b/third_party/WebKit/Source/core/layout/LayoutView.h
@@ -210,6 +210,10 @@
     // have changed.  visibleRect is the clipping boundary.
     void sendMediaPositionChangeNotifications(const IntRect& visibleRect);
 
+    // The rootLayerScrolls setting will ultimately determine whether FrameView
+    // or PaintLayerScrollableArea handle the scroll.
+    ScrollResult scroll(ScrollGranularity, const FloatSize&) override;
+
 private:
     void mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = nullptr, const PaintInvalidationState* = nullptr) const override;
 
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
index ec8cd68..d86e4554 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -707,16 +707,21 @@
         maybeLoadEmpty();
         return;
     }
-    m_mainResource->addClient(this);
-
-    // A bunch of headers are set when the underlying ResourceLoader is created, and m_request needs to include those.
-    if (mainResourceLoader())
+    if (mainResourceLoader()) {
+        // A bunch of headers are set when the underlying ResourceLoader
+        // is created, and m_request needs to include those.
         request = mainResourceLoader()->originalRequest();
+    } else {
+        // Even when using a cached resource, we may make some modification
+        // to the request, e.g. adding the referer header.
+        request = cachedResourceRequest.resourceRequest();
+    }
     // If there was a fragment identifier on m_request, the cache will have stripped it. m_request should include
     // the fragment identifier, so add that back in.
     if (equalIgnoringFragmentIdentifier(m_request.url(), request.url()))
         request.setURL(m_request.url());
     m_request = request;
+    m_mainResource->addClient(this);
 }
 
 void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError)
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp
index af7b78e..b2c67b1 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp
+++ b/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp
@@ -179,7 +179,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("AbortError: the reader is already released", onRejected);
 
@@ -208,7 +208,7 @@
 
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_FALSE(result.isSet);
     EXPECT_EQ("TypeError: the reader is already released", onRejected);
@@ -250,7 +250,7 @@
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(result.isSet);
     EXPECT_FALSE(result.isDone);
@@ -264,7 +264,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(result2.isSet);
     EXPECT_FALSE(result2.isDone);
@@ -290,7 +290,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
@@ -298,7 +298,7 @@
     EXPECT_TRUE(onRejected2.isNull());
 
     m_stream->enqueue("hello");
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(result.isSet);
     EXPECT_FALSE(result.isDone);
@@ -308,7 +308,7 @@
     EXPECT_TRUE(onRejected2.isNull());
 
     m_stream->enqueue("world");
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(result2.isSet);
     EXPECT_FALSE(result2.isDone);
@@ -330,7 +330,7 @@
     String onClosedFulfilled, onClosedRejected;
     ReadResult result;
     String onReadRejected;
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     reader->closed(getScriptState()).then(createCaptor(&onClosedFulfilled), createCaptor(&onClosedRejected));
     reader->read(getScriptState()).then(createResultCaptor(&result), createCaptor(&onReadRejected));
     EXPECT_TRUE(onClosedFulfilled.isNull());
@@ -338,7 +338,7 @@
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onReadRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ("undefined", onClosedFulfilled);
     EXPECT_TRUE(onClosedRejected.isNull());
     EXPECT_TRUE(result.isSet);
@@ -361,7 +361,7 @@
 
     String onClosedFulfilled, onClosedRejected;
     String onReadFulfilled, onReadRejected;
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     reader->closed(getScriptState()).then(createCaptor(&onClosedFulfilled), createCaptor(&onClosedRejected));
     reader->read(getScriptState()).then(createCaptor(&onReadFulfilled), createCaptor(&onReadRejected));
     EXPECT_TRUE(onClosedFulfilled.isNull());
@@ -369,7 +369,7 @@
     EXPECT_TRUE(onReadFulfilled.isNull());
     EXPECT_TRUE(onReadRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_TRUE(onClosedFulfilled.isNull());
     EXPECT_EQ("SyntaxError: some error", onClosedRejected);
     EXPECT_TRUE(onReadFulfilled.isNull());
@@ -389,7 +389,7 @@
     reader->read(getScriptState()).then(createResultCaptor(&result), createCaptor(&onRejected));
     reader->read(getScriptState()).then(createResultCaptor(&result2), createCaptor(&onRejected2));
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_FALSE(result2.isSet);
@@ -401,7 +401,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(result.isSet);
     EXPECT_TRUE(result.isDone);
@@ -427,7 +427,7 @@
     reader->read(getScriptState()).then(createCaptor(&onFulfilled), createCaptor(&onRejected));
     reader->read(getScriptState()).then(createCaptor(&onFulfilled2), createCaptor(&onRejected2));
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_TRUE(onFulfilled2.isNull());
@@ -439,7 +439,7 @@
     EXPECT_TRUE(onFulfilled2.isNull());
     EXPECT_TRUE(onRejected2.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ(onRejected, "SyntaxError: some error");
@@ -460,7 +460,7 @@
     reader->read(getScriptState()).then(createResultCaptor(&result), createCaptor(&onRejected));
     reader->read(getScriptState()).then(createResultCaptor(&result2), createCaptor(&onRejected2));
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_FALSE(result2.isSet);
@@ -473,7 +473,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(result.isSet);
     EXPECT_TRUE(result.isDone);
@@ -502,7 +502,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("TypeError: the reader is already released", onRejected);
@@ -528,7 +528,7 @@
     EXPECT_TRUE(onCancelFulfilled.isNull());
     EXPECT_TRUE(onCancelRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ("undefined", onClosedFulfilled);
     EXPECT_TRUE(onClosedRejected.isNull());
     EXPECT_EQ("undefined", onCancelFulfilled);
@@ -552,7 +552,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_FALSE(exceptionState.hadException());
@@ -574,7 +574,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("SyntaxError: some error", onRejected);
     EXPECT_FALSE(exceptionState.hadException());
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp
index 8ee42c8..63aa1a25 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp
+++ b/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp
@@ -304,7 +304,7 @@
 
     stream->read(getScriptState());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
     EXPECT_FALSE(stream->isPulling());
@@ -335,7 +335,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_TRUE(onRejected.isNull());
 }
@@ -358,7 +358,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("NotFoundError: error", onRejected);
 }
@@ -392,7 +392,7 @@
     EXPECT_TRUE(onCancelFulfilled.isNull());
     EXPECT_TRUE(onCancelRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ("undefined", onCancelFulfilled);
     EXPECT_TRUE(onCancelRejected.isNull());
 }
@@ -416,7 +416,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
 
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("TypeError: this stream is locked to a ReadableStreamReader", onRejected);
@@ -563,7 +563,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_TRUE(onRejected.isNull());
 }
@@ -586,7 +586,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    v8::MicrotasksScope::PerformCheckpoint(isolate());
+    isolate()->RunMicrotasks();
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("SyntaxError: some error", onRejected);
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineProfileTree.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineProfileTree.js
index de512711..6eeb31c 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineProfileTree.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineProfileTree.js
@@ -191,7 +191,7 @@
     var data = event.args["data"] || event.args["beginData"];
     if (data && data["url"])
         return data["url"];
-    var frame = WebInspector.TimelineTreeView.eventStackFrame(event);
+    var frame = WebInspector.TimelineProfileTree.eventStackFrame(event);
     while (frame) {
         var url = frame["url"];
         if (url)
@@ -202,6 +202,21 @@
 }
 
 /**
+ * @param {!WebInspector.TracingModel.Event} event
+ * @return {?Object}
+ */
+WebInspector.TimelineProfileTree.eventStackFrame = function(event)
+{
+    if (event.name == WebInspector.TimelineModel.RecordType.JSFrame)
+        return event.args["data"];
+    var topFrame = event.stackTrace && event.stackTrace[0];
+    if (topFrame)
+        return topFrame;
+    var initiator = event.initiator;
+    return initiator && initiator.stackTrace && initiator.stackTrace[0] || null;
+}
+
+/**
  * @constructor
  * @param {function(!WebInspector.TracingModel.Event):string} categoryMapper
  */
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 7114da07..e8cfc342 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
@@ -291,21 +291,6 @@
 }
 
 /**
- * @param {!WebInspector.TracingModel.Event} event
- * @return {?Object}
- */
-WebInspector.TimelineTreeView.eventStackFrame = function(event)
-{
-    if (event.name == WebInspector.TimelineModel.RecordType.JSFrame)
-        return event.args["data"];
-    var topFrame = event.stackTrace && event.stackTrace[0];
-    if (topFrame)
-        return topFrame;
-    var initiator = event.initiator;
-    return initiator && initiator.stackTrace && initiator.stackTrace[0] || null;
-}
-
-/**
  * @constructor
  * @extends {WebInspector.SortableDataGridNode}
  * @param {!WebInspector.TimelineProfileTree.Node} profileNode
@@ -362,7 +347,7 @@
             name.textContent = event.name === WebInspector.TimelineModel.RecordType.JSFrame
                 ? WebInspector.beautifyFunctionName(event.args["data"]["functionName"])
                 : WebInspector.TimelineUIUtils.eventTitle(event);
-            var frame = WebInspector.TimelineTreeView.eventStackFrame(event);
+            var frame = WebInspector.TimelineProfileTree.eventStackFrame(event);
             if (frame && frame["url"]) {
                 var callFrame = /** @type {!RuntimeAgent.CallFrame} */ (frame);
                 container.createChild("div", "activity-link").appendChild(this._treeView.linkifyLocation(callFrame));
diff --git a/third_party/WebKit/Source/devtools/readme.md b/third_party/WebKit/Source/devtools/readme.md
new file mode 100644
index 0000000..a8ff4a0
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/readme.md
@@ -0,0 +1,38 @@
+# Chrome DevTools frontend
+
+The client-side of the Chrome DevTools, including all JS & CSS to run the DevTools webapp.
+
+It is available on NPM as the [chrome-devtools-frontend](https://www.npmjs.com/package/chrome-devtools-frontend) package. It's not currently available via CJS or ES2015 modules, so consuming this package in other tools may require [some effort](https://github.com/paulirish/devtools-timeline-model/blob/master/index.js).
+
+#### Package versioning
+The version number of the npm package (e.g. `1.0.373466`) refers to the Chromium commit position of latest frontend git commit. It's incremented with every Chromium commit, however the package is updated roughly daily.
+
+
+### Source code
+The frontend is available through a git subtree mirror on [chromium.googlesource.com](https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/devtools/), with a regularly updating GitHub mirror at [github.com/ChromeDevTools/devtools-frontend](https://github.com/ChromeDevTools/devtools-frontend). The codebase's true location is in `third_party/WebKit/Source/devtools/` in [Chromium's git repo](https://chromium.googlesource.com/chromium/src/).
+
+
+
+### Hacking
+* DevTools documentation: [devtools.chrome.com](https://devtools.chrome.com)
+* [Debugging protocol docs](https://developer.chrome.com/devtools/docs/debugger-protocol) and [Chrome Debugging Protocol Viewer](http://chromedevtools.github.io/debugger-protocol-viewer/)
+* [awesome-chrome-devtools](https://github.com/paulirish/awesome-chrome-devtools): recommended tools and resources
+* Contributing to DevTools: [bit.ly/devtools-contribution-guide](http://bit.ly/devtools-contribution-guide)
+
+
+#### Development
+* All devtools commits: [View the log], [RSS feed] or [@DevToolsCommits] on Twitter
+* [All open DevTools tickets] on crbug.com
+* File a new DevTools ticket: [new.crbug.com](https://bugs.chromium.org/p/chromium/issues/entry?labels=OS-All,Type-Bug,Pri-2&components=Platform%3EDevTools)
+* Code reviews mailing list: [devtools-reviews@chromium.org]
+
+### Getting in touch
+* [@ChromeDevTools] on Twitter
+* Chrome DevTools mailing list: [groups.google.com/forum/google-chrome-developer-tools](https://groups.google.com/forum/#!forum/google-chrome-developer-tools)
+
+  [devtools-reviews@chromium.org]: https://groups.google.com/a/chromium.org/forum/#!forum/devtools-reviews
+  [RSS feed]: https://feeds.peter.sh/chrome-devtools/
+  [View the log]: https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/devtools/+log/master
+  [@ChromeDevTools]: http://twitter.com/ChromeDevTools
+  [@DevToolsCommits]: http://twitter.com/DevToolsCommits
+  [all open DevTools tickets]: https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3APlatform%3EDevTools&sort=&groupby=&colspec=ID+Stars+Owner+Summary+Modified+Opened
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
index 37efbf4..8654688 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -1535,14 +1535,9 @@
     if (parentObj)
         return axObjectCache().getOrCreate(parentObj);
 
-    // A WebArea's parent should be the containing frame (if local) or page popup owner.
+    // A WebArea's parent should be the page popup owner, if any, otherwise null.
     if (isWebArea()) {
         LocalFrame* frame = m_layoutObject->frame();
-        if (frame->owner() && frame->owner()->isLocal()) {
-            HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(frame->owner());
-            if (owner && owner->layoutObject())
-                return axObjectCache().getOrCreate(owner->layoutObject());
-        }
         return axObjectCache().getOrCreate(frame->pagePopupOwner());
     }
 
@@ -1568,14 +1563,9 @@
     if (parentObj)
         return axObjectCache().get(parentObj);
 
-    // A WebArea's parent should be the containing frame (if local) or page popup owner.
+    // A WebArea's parent should be the page popup owner, if any, otherwise null.
     if (isWebArea()) {
         LocalFrame* frame = m_layoutObject->frame();
-        if (frame->owner() && frame->owner()->isLocal()) {
-            HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(frame->owner());
-            if (owner && owner->layoutObject())
-                return axObjectCache().get(owner->layoutObject());
-        }
         return axObjectCache().get(frame->pagePopupOwner());
     }
 
@@ -1666,7 +1656,6 @@
     }
 
     addHiddenChildren();
-    addFrameChildren();
     addPopupChildren();
     addImageMapChildren();
     addTextFieldChildren();
@@ -2455,24 +2444,6 @@
     AXNodeObject::addChildren();
 }
 
-void AXLayoutObject::addFrameChildren()
-{
-    if (!m_layoutObject || !m_layoutObject->isLayoutPart())
-        return;
-
-    Widget* widget = toLayoutPart(m_layoutObject)->widget();
-    if (!widget || !widget->isFrameView())
-        return;
-
-    Document* doc = toFrameView(widget)->frame().document();
-    if (!doc || !doc->layoutView())
-        return;
-
-    AXObject* axChildFrame = axObjectCache().getOrCreate(doc);
-    if (!axChildFrame->accessibilityIsIgnored())
-        m_children.append(axChildFrame);
-}
-
 void AXLayoutObject::addPopupChildren()
 {
     if (!isHTMLInputElement(getNode()))
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h
index 0610bac..e43355ab 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h
+++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h
@@ -208,7 +208,6 @@
     void addTextFieldChildren();
     void addImageMapChildren();
     void addCanvasChildren();
-    void addFrameChildren();
     void addPopupChildren();
     void addRemoteSVGChildren();
     void addInlineTextBoxChildren(bool force);
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
index 0a764099..6b21c0c82 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.cpp
@@ -157,25 +157,16 @@
     if (!accessibilityEnabled())
         return 0;
 
-    // We don't have to return anything if the focused frame is not local;
-    // the remote frame will have its own AXObjectCacheImpl and the focused
-    // object will be sorted out by the browser process.
-    Page* page = m_document->page();
-    if (!page->focusController().focusedFrame())
-        return 0;
-
-    // Get the focused node in the page.
-    Document* focusedDocument = page->focusController().focusedFrame()->document();
-    Node* focusedNode = focusedDocument->focusedElement();
+    Node* focusedNode = m_document->focusedElement();
     if (!focusedNode)
-        focusedNode = focusedDocument;
+        focusedNode = m_document;
 
     // If it's an image map, get the focused link within the image map.
     if (isHTMLAreaElement(focusedNode))
         return focusedImageMapUIElement(toHTMLAreaElement(focusedNode));
 
     // See if there's a page popup, for example a calendar picker.
-    Element* adjustedFocusedElement = focusedDocument->adjustedFocusedElement();
+    Element* adjustedFocusedElement = m_document->adjustedFocusedElement();
     if (isHTMLInputElement(adjustedFocusedElement)) {
         if (AXObject* axPopup = toHTMLInputElement(adjustedFocusedElement)->popupRootAXObject()) {
             if (Element* focusedElementInPopup = axPopup->getDocument()->focusedElement())
diff --git a/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp b/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp
index fcd57501..df86cda 100644
--- a/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp
+++ b/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp
@@ -249,7 +249,7 @@
     {
         ScriptValue onReject;
         promise.then(UnreachableFunction::create(getScriptState()), TestFunction::create(getScriptState(), &onReject));
-        v8::MicrotasksScope::PerformCheckpoint(isolate());
+        isolate()->RunMicrotasks();
         return onReject;
     }
 
@@ -263,7 +263,7 @@
     {
         ScriptValue onResolve;
         promise.then(TestFunction::create(getScriptState(), &onResolve), UnreachableFunction::create(getScriptState()));
-        v8::MicrotasksScope::PerformCheckpoint(isolate());
+        isolate()->RunMicrotasks();
         return onResolve;
     }
 
diff --git a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
index 00c3fa65..4d19f76 100644
--- a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
+++ b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
@@ -8,7 +8,6 @@
 #include "bindings/core/v8/ScriptState.h"
 #include "bindings/core/v8/V8BindingMacros.h"
 #include "bindings/core/v8/V8GCController.h"
-#include "bindings/core/v8/V8RecursionScope.h"
 #include "core/dom/Document.h"
 #include "core/testing/DummyPageHolder.h"
 #include "modules/fetch/DataConsumerHandleTestUtil.h"
@@ -60,7 +59,6 @@
     {
         v8::Local<v8::String> source;
         v8::Local<v8::Script> script;
-        V8RecursionScope::MicrotaskSuppression microtasks(isolate());
         if (!v8Call(v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNormal), source)) {
             ADD_FAILURE();
             return v8::MaybeLocal<v8::Value>();
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
index a2409dd2..37d0f14 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
@@ -92,7 +92,7 @@
 {
     StubScriptFunction resolved, rejected;
     promise.then(resolved.function(scriptState), rejected.function(scriptState));
-    v8::MicrotasksScope::PerformCheckpoint(promise.isolate());
+    promise.isolate()->RunMicrotasks();
     EXPECT_EQ(0ul, resolved.callCount());
     EXPECT_EQ(1ul, rejected.callCount());
     if (rejected.callCount())
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index 8255b6a9..ce0600d5 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -145,7 +145,7 @@
   deps = [
     ":character_data_generator($host_toolchain)",
   ]
-  output_file = "$blink_platform_output_dir/CharacterData.cpp"
+  output_file = "$blink_platform_output_dir/CharacterPropertyData.cpp"
   outputs = [
     output_file,
   ]
@@ -164,7 +164,8 @@
 
 executable("character_data_generator") {
   sources = [
-    "fonts/CharacterDataGenerator.cpp",
+    "fonts/CharacterPropertyDataGenerator.cpp",
+    "fonts/CharacterPropertyDataGenerator.h",
   ]
   configs += [ "//third_party/WebKit/Source:config" ]
   deps = [
diff --git a/third_party/WebKit/Source/platform/blink_platform.gyp b/third_party/WebKit/Source/platform/blink_platform.gyp
index 4be09cc..9f7ac0e 100644
--- a/third_party/WebKit/Source/platform/blink_platform.gyp
+++ b/third_party/WebKit/Source/platform/blink_platform.gyp
@@ -182,7 +182,7 @@
       '<@(platform_heap_files)',
 
       # Additional .cpp files from platform_generated.gyp:make_platform_generated actions.
-      '<(blink_platform_output_dir)/CharacterData.cpp',
+      '<(blink_platform_output_dir)/CharacterPropertyData.cpp',
       '<(blink_platform_output_dir)/ColorData.cpp',
       '<(blink_platform_output_dir)/FontFamilyNames.cpp',
       '<(blink_platform_output_dir)/HTTPNames.cpp',
diff --git a/third_party/WebKit/Source/platform/exported/Platform.cpp b/third_party/WebKit/Source/platform/exported/Platform.cpp
index 72904f7..ff4f19ed 100644
--- a/third_party/WebKit/Source/platform/exported/Platform.cpp
+++ b/third_party/WebKit/Source/platform/exported/Platform.cpp
@@ -59,12 +59,12 @@
 
 void Platform::initialize(Platform* platform)
 {
+    ASSERT(platform);
     s_platform = platform;
-    if (s_platform)
-        s_platform->m_mainThread = platform->currentThread();
+    s_platform->m_mainThread = platform->currentThread();
 
     // TODO(ssid): remove this check after fixing crbug.com/486782.
-    if (s_platform && s_platform->m_mainThread)
+    if (s_platform->m_mainThread)
         s_platform->registerMemoryDumpProvider(PartitionAllocMemoryDumpProvider::instance(), "PartitionAlloc");
 
     CompositorFactory::initializeDefault();
@@ -77,9 +77,15 @@
     if (s_platform->m_mainThread)
         s_platform->unregisterMemoryDumpProvider(PartitionAllocMemoryDumpProvider::instance());
 
-    if (s_platform)
-        s_platform->m_mainThread = 0;
-    s_platform = 0;
+    s_platform->m_mainThread = nullptr;
+    s_platform = nullptr;
+}
+
+void Platform::setCurrentPlatformForTesting(Platform* platform)
+{
+    ASSERT(platform);
+    s_platform = platform;
+    s_platform->m_mainThread = platform->currentThread();
 }
 
 Platform* Platform::current()
diff --git a/third_party/WebKit/Source/platform/fonts/Character.cpp b/third_party/WebKit/Source/platform/fonts/Character.cpp
index 2616179..a7bc156 100644
--- a/third_party/WebKit/Source/platform/fonts/Character.cpp
+++ b/third_party/WebKit/Source/platform/fonts/Character.cpp
@@ -37,7 +37,7 @@
 #include <unicode/uscript.h>
 
 #if defined(USING_SYSTEM_ICU)
-#include "CharacterData.h"
+#include "platform/fonts/CharacterPropertyDataGenerator.h"
 #include <unicode/uniset.h>
 #else
 #define MUTEX_H // Prevent compile failure of utrie2.h on Windows
@@ -190,6 +190,12 @@
             if (supplementaryCharacter <= 0x1F1FF)
                 return ComplexPath;
 
+            // Emoji Fitzpatrick modifiers trigger upgrade to complex path for shaping them.
+            if (supplementaryCharacter < 0x1F3FB)
+                continue;
+            if (supplementaryCharacter <= 0x1F3FF)
+                return ComplexPath;
+
             // Man and Woman Emojies,
             // in order to support emoji joiner combinations for family and couple pictographs.
             // Compare http://unicode.org/reports/tr51/#Emoji_ZWJ_Sequences
diff --git a/third_party/WebKit/Source/platform/fonts/CharacterData.cpp b/third_party/WebKit/Source/platform/fonts/CharacterData.cpp
deleted file mode 100644
index 0dca947c..0000000
--- a/third_party/WebKit/Source/platform/fonts/CharacterData.cpp
+++ /dev/null
@@ -1,634 +0,0 @@
-#include <cstdint>
-
-namespace blink {
-
-int32_t serializedCharacterDataSize = 10000;
-uint8_t serializedCharacterData[] = {
-    0x32, 0x69, 0x72, 0x54, 0x00, 0x00, 0x14, 0x0C, 0xDB, 0x01, 0x40, 0x00, 0x14, 0x0C, 0x20, 0x02,
-    0x05, 0x03, 0x0D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x2C, 0x03, 0x34, 0x03, 0x3C, 0x03, 0x44, 0x03,
-    0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03,
-    0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x4B, 0x03, 0x53, 0x03,
-    0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03,
-    0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03,
-    0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03,
-    0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03,
-    0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03, 0x05, 0x03, 0x0D, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x63, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x57, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x6B, 0x03, 0x73, 0x03, 0x7B, 0x03, 0x82, 0x03, 0x05, 0x03, 0x05, 0x03, 0x85, 0x03, 0x8D, 0x03,
-    0x95, 0x03, 0x9D, 0x03, 0xA5, 0x03, 0xAD, 0x03, 0xB5, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0xB9, 0x03, 0xC1, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0xC9, 0x03, 0xD1, 0x03, 0x05, 0x03, 0xD4, 0x03, 0xDC, 0x03, 0xE3, 0x03, 0xEB, 0x03, 0xF3, 0x03,
-    0x5B, 0x03, 0xFB, 0x03, 0x5B, 0x03, 0x03, 0x04, 0x07, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x0F, 0x04, 0x16, 0x04, 0x1E, 0x04,
-    0x26, 0x04, 0x5B, 0x03, 0x2E, 0x04, 0x36, 0x04, 0x5B, 0x03, 0x3E, 0x04, 0x5B, 0x03, 0x5B, 0x03,
-    0x46, 0x04, 0x4D, 0x04, 0x55, 0x04, 0x5D, 0x04, 0x66, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x65, 0x04, 0x67, 0x03, 0x6D, 0x04, 0x05, 0x03, 0x05, 0x03, 0x74, 0x04, 0x5B, 0x03, 0x5B, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0xFF, 0x03,
-    0x03, 0x04, 0x7C, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x81, 0x04, 0x5B, 0x03, 0x5B, 0x03, 0xFF, 0x03, 0x03, 0x04, 0x03, 0x04, 0x81, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x5B, 0x03, 0x5B, 0x03,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x67, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x5B, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x89, 0x04, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x91, 0x04, 0x99, 0x04, 0x9F, 0x04, 0xA7, 0x04, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0xAF, 0x04, 0x03, 0x04, 0x03, 0x04, 0xB7, 0x04, 0xB8, 0x04, 0xB8, 0x04, 0xB8, 0x04, 0xC0, 0x04,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x94, 0x0C, 0x94, 0x0C, 0xB0, 0x0C, 0xF0, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C,
-    0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x2C, 0x0D, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C,
-    0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C,
-    0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C, 0x14, 0x0C,
-    0x40, 0x00, 0x40, 0x0A, 0x54, 0x0A, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x05, 0x05, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xB8, 0x06, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x94, 0x0A, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xD4, 0x0A, 0x40, 0x00,
-    0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01,
-    0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01,
-    0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x14, 0x0B, 0x90, 0x01, 0x90, 0x01, 0x53, 0x0B,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x93, 0x0B,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0xD3, 0x0B,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0xD3, 0x0B,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
-    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0xD3, 0x0B,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x5B, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03,
-    0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x05, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0xC8, 0x04, 0xCE, 0x04, 0xCE, 0x04, 0xCE, 0x04,
-    0xD4, 0x04, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x5B, 0x03, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04,
-    0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0xD7, 0x04, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03, 0x5B, 0x03,
-    0x5B, 0x03, 0x5B, 0x03, 0xD7, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
-    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
-    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
-    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
-    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
-    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
-    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
-    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/CharacterPropertyData.cpp b/third_party/WebKit/Source/platform/fonts/CharacterPropertyData.cpp
new file mode 100644
index 0000000..9d62d58
--- /dev/null
+++ b/third_party/WebKit/Source/platform/fonts/CharacterPropertyData.cpp
@@ -0,0 +1,652 @@
+#include <cstdint>
+
+namespace blink {
+
+int32_t serializedCharacterDataSize = 10288;
+uint8_t serializedCharacterData[] = {
+    0x32, 0x69, 0x72, 0x54, 0x00, 0x00, 0x54, 0x0C, 0xEF, 0x01, 0x40, 0x00, 0x54, 0x0C, 0x20, 0x02,
+    0x15, 0x03, 0x1D, 0x03, 0x25, 0x03, 0x2D, 0x03, 0x3C, 0x03, 0x44, 0x03, 0x4C, 0x03, 0x54, 0x03,
+    0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03,
+    0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x5B, 0x03, 0x63, 0x03,
+    0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03,
+    0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03,
+    0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03,
+    0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03,
+    0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03, 0x15, 0x03, 0x1D, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x73, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x67, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x7B, 0x03, 0x83, 0x03, 0x8B, 0x03, 0x92, 0x03, 0x15, 0x03, 0x15, 0x03, 0x95, 0x03, 0x9D, 0x03,
+    0xA5, 0x03, 0xAD, 0x03, 0xB5, 0x03, 0xBD, 0x03, 0xC5, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0xC9, 0x03, 0xD1, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0xD9, 0x03, 0xE1, 0x03, 0x15, 0x03, 0xE4, 0x03, 0xEC, 0x03, 0xF3, 0x03, 0xFB, 0x03, 0x03, 0x04,
+    0x6B, 0x03, 0x0B, 0x04, 0x6B, 0x03, 0x13, 0x04, 0x17, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x1F, 0x04, 0x26, 0x04, 0x2E, 0x04,
+    0x36, 0x04, 0x6B, 0x03, 0x3E, 0x04, 0x46, 0x04, 0x6B, 0x03, 0x4E, 0x04, 0x6B, 0x03, 0x56, 0x04,
+    0x5D, 0x04, 0x64, 0x04, 0x6C, 0x04, 0x74, 0x04, 0x76, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x7C, 0x04, 0x77, 0x03, 0x84, 0x04, 0x15, 0x03, 0x15, 0x03, 0x8B, 0x04, 0x6B, 0x03, 0x6B, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x0F, 0x04,
+    0x13, 0x04, 0x93, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x98, 0x04, 0x6B, 0x03, 0x6B, 0x03, 0x0F, 0x04, 0x13, 0x04, 0x13, 0x04, 0x98, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x6B, 0x03, 0x6B, 0x03,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x77, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x6B, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0xA0, 0x04, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0xA8, 0x04, 0xB0, 0x04, 0xB6, 0x04, 0xBE, 0x04, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0xC6, 0x04, 0x13, 0x04, 0x13, 0x04, 0xCE, 0x04, 0xCF, 0x04, 0xCF, 0x04, 0xCF, 0x04, 0xD7, 0x04,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0xD4, 0x0C, 0xD4, 0x0C, 0xF0, 0x0C, 0x30, 0x0D, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C,
+    0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x6C, 0x0D, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C,
+    0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C,
+    0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C, 0x54, 0x0C,
+    0x40, 0x00, 0x40, 0x0A, 0x54, 0x0A, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x05, 0x05, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xB8, 0x06, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x94, 0x0A, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xD4, 0x0A, 0x14, 0x0B,
+    0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01,
+    0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01,
+    0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x90, 0x01, 0x54, 0x0B, 0x90, 0x01, 0x90, 0x01, 0x93, 0x0B,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0xD3, 0x0B,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x13, 0x0C,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x13, 0x0C,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05,
+    0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x60, 0x05, 0x13, 0x0C,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x6B, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0xDF, 0x04, 0xE5, 0x04, 0xE5, 0x04, 0xE5, 0x04,
+    0xEB, 0x04, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0xF3, 0x04, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03,
+    0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x15, 0x03, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x6B, 0x03, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04,
+    0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x13, 0x04, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0xFB, 0x04, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03, 0x6B, 0x03,
+    0x6B, 0x03, 0x6B, 0x03, 0xFB, 0x04, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/CharacterDataGenerator.cpp b/third_party/WebKit/Source/platform/fonts/CharacterPropertyDataGenerator.cpp
similarity index 93%
rename from third_party/WebKit/Source/platform/fonts/CharacterDataGenerator.cpp
rename to third_party/WebKit/Source/platform/fonts/CharacterPropertyDataGenerator.cpp
index a6c6ca3..02bf1a6 100644
--- a/third_party/WebKit/Source/platform/fonts/CharacterDataGenerator.cpp
+++ b/third_party/WebKit/Source/platform/fonts/CharacterPropertyDataGenerator.cpp
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "CharacterData.h"
+// TODO(kojii): This file is compiled with $host_toolchain, which cannot find
+// include files in platform/fonts. The build scripts should include this
+// directory, and fix these #include's to "platform/fonts/...".
+#include "CharacterPropertyDataGenerator.h"
 
 #include "CharacterProperty.h"
 #include <cassert>
diff --git a/third_party/WebKit/Source/platform/fonts/CharacterData.h b/third_party/WebKit/Source/platform/fonts/CharacterPropertyDataGenerator.h
similarity index 92%
rename from third_party/WebKit/Source/platform/fonts/CharacterData.h
rename to third_party/WebKit/Source/platform/fonts/CharacterPropertyDataGenerator.h
index a9c8f21..07c19506 100644
--- a/third_party/WebKit/Source/platform/fonts/CharacterData.h
+++ b/third_party/WebKit/Source/platform/fonts/CharacterPropertyDataGenerator.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 CharacterData_h
-#define CharacterData_h
+#ifndef CharacterPropertyDataGenerator_h
+#define CharacterPropertyDataGenerator_h
 
 #include <unicode/uobject.h>
 
@@ -23,9 +23,9 @@
     0x212B, 0x213B, 0x2150, 0x2151, 0x2152, 0x217F, 0x2189, 0x2307, 0x2312, 0x23CE,
     0x2423, 0x25A0, 0x25A1, 0x25A2, 0x25AA, 0x25AB, 0x25B1, 0x25B2, 0x25B3, 0x25B6,
     0x25B7, 0x25BC, 0x25BD, 0x25C0, 0x25C1, 0x25C6, 0x25C7, 0x25C9, 0x25CB, 0x25CC,
-    0x25EF, 0x2605, 0x2606, 0x260E, 0x2616, 0x2617, 0x2640, 0x2642, 0x26A0, 0x26BD,
-    0x26BE, 0x2713, 0x271A, 0x273F, 0x2740, 0x2756, 0x2B1A, 0xFE10, 0xFE11, 0xFE12,
-    0xFE19, 0xFF1D,
+    0x25EF, 0x2605, 0x2606, 0x260E, 0x2616, 0x2617, 0x261D, 0x2640, 0x2642, 0x26A0,
+    0x26BD, 0x26BE, 0x26F9, 0x2713, 0x271A, 0x273F, 0x2740, 0x2756, 0x2B1A, 0xFE10,
+    0xFE11, 0xFE12, 0xFE19, 0xFF1D,
     // Emoji.
     0x1F100
 };
@@ -68,6 +68,9 @@
     0x2763, 0x2764,
     0x2672, 0x267D,
     0x2776, 0x277F,
+    // Hand signs needed in order
+    // not to break Emoji modifier sequences.
+    0x270A, 0x270D,
     // Ideographic Description Characters, with CJK Symbols and Punctuation,
     // excluding 0x3030.
     // Then Hiragana 0x3040 .. 0x309F, Katakana 0x30A0 .. 0x30FF, Bopomofo
@@ -92,7 +95,11 @@
     0x1F130, 0x1F149,
     0x1F150, 0x1F169,
     0x1F170, 0x1F189,
-    0x1F200, 0x1F6FF
+    0x1F200, 0x1F6FF,
+    // Modifiers
+    0x1F3FB, 0x1F3FF,
+    // ZIPPER-MOUTH FACE...SIGN OF THE HORNS
+    0x1F910, 0x1F918
 };
 
 // Individual codepoints needed for Unicode vertical text layout according to
diff --git a/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp b/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp
index 722366ec..02b6cb7 100644
--- a/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp
+++ b/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp
@@ -175,6 +175,11 @@
     CHECK_RUNS({ { "👶🏿", FontFallbackPriority::EmojiEmoji } });
 }
 
+TEST_F(SymbolsIteratorTest, DingbatsMiscSymbolsModifier)
+{
+    CHECK_RUNS({ { "⛹🏻✍🏻✊🏼", FontFallbackPriority::EmojiEmoji } });
+}
+
 TEST_F(SymbolsIteratorTest, ExtraZWJPrefix)
 {
     CHECK_RUNS({ { "\xE2\x80\x8D", FontFallbackPriority::Text },
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h
index 0d7ad28..75cc46e 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h
@@ -127,9 +127,9 @@
                 bool hasAnyScript = !Character::isCommonOrInheritedScript(ch);
                 for (unsigned i = end; i < length; end = i) {
                     U16_NEXT(m_textRun.characters16(), i, length, ch);
-                    // ZWJ check in order not to split Emoji ZWJ sequences.
+                    // ZWJ and modifier check in order not to split those Emoji sequences.
                     if (U_GET_GC_MASK(ch) & (U_GC_M_MASK | U_GC_LM_MASK | U_GC_SK_MASK)
-                        || ch == zeroWidthJoinerCharacter)
+                        || ch == zeroWidthJoinerCharacter || Character::isModifier(ch))
                         continue;
                     // Avoid delimiting COMMON/INHERITED alone, which makes harder to
                     // identify the script.
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaperTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaperTest.cpp
index a019153..cac30b8 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaperTest.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaperTest.cpp
@@ -351,6 +351,25 @@
     ASSERT_FALSE(iterator.next(&wordResult));
 }
 
+TEST_F(CachingWordShaperTest, SegmentEmojiSignsOfHornsModifier)
+{
+    // A Sign of the Horns emoji, followed by a fitzpatrick modifer
+    const UChar str[] = {
+        0xD83E, 0xDD18,
+        0xD83C, 0xDFFB,
+        0x0
+    };
+    TextRun textRun(str, 4);
+
+    RefPtr<ShapeResult> wordResult;
+    CachingWordShapeIterator iterator(cache.get(), textRun, &font);
+
+    ASSERT_TRUE(iterator.next(&wordResult));
+    EXPECT_EQ(4u, wordResult->numCharacters());
+
+    ASSERT_FALSE(iterator.next(&wordResult));
+}
+
 TEST_F(CachingWordShaperTest, SegmentEmojiExtraZWJPrefix)
 {
     // A ZWJ, followed by a family and a heart-kiss sequence.
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
index 29ddc126..b946a26 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
@@ -107,8 +107,6 @@
             character = spaceCharacter;
         else if (Character::treatAsZeroWidthSpaceInComplexScript(character))
             character = zeroWidthSpaceCharacter;
-        else if (Character::isModifier(character))
-            character = zeroWidthSpaceCharacter;
 
         U16_APPEND(destination, *destinationLength, length, character, error);
         ASSERT_UNUSED(error, !error);
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp
index 7e4bd9e..6499faa 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp
@@ -210,6 +210,12 @@
     });
 }
 
+TEST_F(RunSegmenterTest, DingbatsMiscSymbolsModifier)
+{
+    CHECK_RUNS_HORIZONTAL_NORMAL({ { "⛹🏻✍🏻✊🏼", USCRIPT_UNKNOWN, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsSameCase, FontFallbackPriority::EmojiEmoji } });
+}
+
+
 TEST_F(RunSegmenterTest, ArmenianCyrillicSmallCaps)
 {
     CHECK_RUNS_HORIZONTAL_SMALLCAPS({ { "աբգ", USCRIPT_ARMENIAN, OrientationIterator::OrientationKeep, SmallCapsIterator::SmallCapsUppercaseNeeded, FontFallbackPriority::Text },
diff --git a/third_party/WebKit/Source/platform/fonts/win/FontFallbackWin.cpp b/third_party/WebKit/Source/platform/fonts/win/FontFallbackWin.cpp
index c2a17f5..8208a33 100644
--- a/third_party/WebKit/Source/platform/fonts/win/FontFallbackWin.cpp
+++ b/third_party/WebKit/Source/platform/fonts/win/FontFallbackWin.cpp
@@ -194,7 +194,7 @@
     static const UChar* runicFonts[] = { L"Segoe UI Historic",
         L"Segoe UI Symbol", 0 };
     static const UChar* shavianFonts[] = { L"Segoe UI Historic", 0 };
-    static const UChar* simplifiedHanFonts[] = { L"simsun", L"Microsoft YaHei",
+    static const UChar* simplifiedHanFonts[] = { L"Microsoft YaHei", L"simsun",
         0 };
     static const UChar* sinhalaFonts[] = { L"Iskoola Pota", L"AksharUnicode",
         L"Nirmala UI", 0 };
@@ -211,8 +211,8 @@
     static const UChar* tibetanFonts[] = { L"Microsoft Himalaya", L"Jomolhari",
         L"Tibetan Machine Uni", 0 };
     static const UChar* tifinaghFonts[] = { L"Ebrima", 0 };
-    static const UChar* traditionalHanFonts[] = { L"pmingliu",
-        L"Microsoft JhengHei", 0 };
+    static const UChar* traditionalHanFonts[] = { L"Microsoft JhengHei",
+        L"pmingliu", 0 };
     static const UChar* vaiFonts[] = { L"Ebrima", 0 };
     static const UChar* yiFonts[] = { L"Microsoft Yi Baiti", L"Nuosu SIL",
         L"Code2000", 0 };
diff --git a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
index 64d6223..d857ae67 100644
--- a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
@@ -75,23 +75,27 @@
     return decoded;
 }
 
-bool DecodingImageGenerator::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], SkYUVColorSpace* colorSpace)
+bool DecodingImageGenerator::onQueryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const
 {
     if (!m_canYUVDecode)
         return false;
 
-    bool requestingYUVSizes = !planes || !planes[0];
-
-    TRACE_EVENT1("blink", "DecodingImageGenerator::getYUV8Planes", requestingYUVSizes ? "sizes" : "frame index", static_cast<int>(m_frameIndex));
-
-    if (requestingYUVSizes)
-        return m_frameGenerator->getYUVComponentSizes(sizes);
+    TRACE_EVENT1("blink", "DecodingImageGenerator::queryYUV8", "sizes", static_cast<int>(m_frameIndex));
 
     if (colorSpace)
         *colorSpace = kJPEG_SkYUVColorSpace;
 
+    return m_frameGenerator->getYUVComponentSizes(sizeInfo);
+}
+
+bool DecodingImageGenerator::onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3])
+{
+    ASSERT(m_canYUVDecode);
+
+    TRACE_EVENT1("blink", "DecodingImageGenerator::getYUV8Planes", "frame index", static_cast<int>(m_frameIndex));
+
     PlatformInstrumentation::willDecodeLazyPixelRef(m_generationId);
-    bool decoded = m_frameGenerator->decodeToYUV(m_frameIndex, sizes, planes, rowBytes);
+    bool decoded = m_frameGenerator->decodeToYUV(m_frameIndex, sizeInfo.fSizes, planes, sizeInfo.fWidthBytes);
     PlatformInstrumentation::didDecodeLazyPixelRef();
 
     return decoded;
diff --git a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h
index 64e0895..65407af 100644
--- a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h
+++ b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h
@@ -59,7 +59,9 @@
 
     bool onGetPixels(const SkImageInfo&, void* pixels, size_t rowBytes, SkPMColor table[], int* tableCount) override;
 
-    bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], SkYUVColorSpace*) override;
+    bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const override;
+
+    bool onGetYUV8Planes(const SkYUVSizeInfo&, void* planes[3]) override;
 
 private:
     RefPtr<ImageFrameGenerator> m_frameGenerator;
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
index edb8bf4..4800a31 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
@@ -84,17 +84,20 @@
     size_t m_rowBytes;
 };
 
-static bool updateYUVComponentSizes(ImageDecoder* decoder, SkISize componentSizes[3], ImageDecoder::SizeType sizeType)
+static bool updateYUVComponentSizes(ImageDecoder* decoder, SkISize componentSizes[3], size_t componentWidthBytes[3])
 {
     if (!decoder->canDecodeToYUV())
         return false;
 
-    IntSize size = decoder->decodedYUVSize(0, sizeType);
+    IntSize size = decoder->decodedYUVSize(0);
     componentSizes[0].set(size.width(), size.height());
-    size = decoder->decodedYUVSize(1, sizeType);
+    componentWidthBytes[0] = decoder->decodedYUVWidthBytes(0);
+    size = decoder->decodedYUVSize(1);
     componentSizes[1].set(size.width(), size.height());
-    size = decoder->decodedYUVSize(2, sizeType);
+    componentWidthBytes[1] = decoder->decodedYUVWidthBytes(1);
+    size = decoder->decodedYUVSize(2);
     componentSizes[2].set(size.width(), size.height());
+    componentWidthBytes[2] = decoder->decodedYUVWidthBytes(2);
     return true;
 }
 
@@ -206,7 +209,7 @@
     return true;
 }
 
-bool ImageFrameGenerator::decodeToYUV(size_t index, SkISize componentSizes[3], void* planes[3], size_t rowBytes[3])
+bool ImageFrameGenerator::decodeToYUV(size_t index, const SkISize componentSizes[3], void* planes[3], const size_t rowBytes[3])
 {
     // Prevent concurrent decode or scale operations on the same image data.
     MutexLocker lock(m_decodeMutex);
@@ -237,8 +240,7 @@
     OwnPtr<ImagePlanes> imagePlanes = adoptPtr(new ImagePlanes(planes, rowBytes));
     decoder->setImagePlanes(imagePlanes.release());
 
-    bool sizeUpdated = updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder::ActualSize);
-    RELEASE_ASSERT(sizeUpdated);
+    ASSERT(decoder->canDecodeToYUV());
 
     if (decoder->decodeToYUV()) {
         setHasAlpha(0, false); // YUV is always opaque
@@ -389,7 +391,7 @@
     return true;
 }
 
-bool ImageFrameGenerator::getYUVComponentSizes(SkISize componentSizes[3])
+bool ImageFrameGenerator::getYUVComponentSizes(SkYUVSizeInfo* sizeInfo)
 {
     TRACE_EVENT2("blink", "ImageFrameGenerator::getYUVComponentSizes", "width", m_fullSize.width(), "height", m_fullSize.height());
 
@@ -410,8 +412,7 @@
     OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes);
     decoder->setImagePlanes(dummyImagePlanes.release());
 
-    ASSERT(componentSizes);
-    return updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder::SizeForMemoryAllocation);
+    return updateYUVComponentSizes(decoder.get(), sizeInfo->fSizes, sizeInfo->fWidthBytes);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
index 71553cb..bd52b9b 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
@@ -31,6 +31,7 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkSize.h"
 #include "third_party/skia/include/core/SkTypes.h"
+#include "third_party/skia/include/core/SkYUVSizeInfo.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/PassOwnPtr.h"
@@ -80,7 +81,7 @@
     bool decodeAndScale(size_t index, const SkImageInfo&, void* pixels, size_t rowBytes);
 
     // Decodes YUV components directly into the provided memory planes.
-    bool decodeToYUV(size_t index, SkISize componentSizes[3], void* planes[3], size_t rowBytes[3]);
+    bool decodeToYUV(size_t index, const SkISize componentSizes[3], void* planes[3], const size_t rowBytes[3]);
 
     const SkISize& getFullSize() const { return m_fullSize; }
 
@@ -89,7 +90,7 @@
 
     bool hasAlpha(size_t index);
 
-    bool getYUVComponentSizes(SkISize componentSizes[3]);
+    bool getYUVComponentSizes(SkYUVSizeInfo*);
 
 private:
     ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<SharedBuffer>, bool allDataReceived, bool isMultiFrame);
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp
index 5a67eb1..faa95c99 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.cpp
+++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -673,7 +673,6 @@
 CallbackStack* Heap::s_globalWeakCallbackStack;
 CallbackStack* Heap::s_ephemeronStack;
 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache;
-bool Heap::s_shutdownCalled = false;
 FreePagePool* Heap::s_freePagePool;
 OrphanedPagePool* Heap::s_orphanedPagePool;
 RegionTree* Heap::s_regionTree = nullptr;
diff --git a/third_party/WebKit/Source/platform/heap/Heap.h b/third_party/WebKit/Source/platform/heap/Heap.h
index 95fac29..1930694 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.h
+++ b/third_party/WebKit/Source/platform/heap/Heap.h
@@ -315,7 +315,6 @@
     static CallbackStack* s_globalWeakCallbackStack;
     static CallbackStack* s_ephemeronStack;
     static HeapDoesNotContainCache* s_heapDoesNotContainCache;
-    static bool s_shutdownCalled;
     static FreePagePool* s_freePagePool;
     static OrphanedPagePool* s_orphanedPagePool;
     static RegionTree* s_regionTree;
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index 1dcd122..ee21153 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -5751,54 +5751,6 @@
     RecursiveLockingTester::test();
 }
 
-class CrossThreadPersistentOnMainThreadTester {
-public:
-    static void test()
-    {
-        MutexLocker locker(mainThreadMutex());
-        OwnPtr<WebThread> workerThread = adoptPtr(Platform::current()->createThread("Test Worker Thread"));
-        workerThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(workerThreadMain));
-
-        parkMainThread();
-
-        // (Temporarily) detach main thread and wake the worker thread, so that it
-        // can do its detach().
-        ThreadState::detachMainThread();
-        wakeWorkerThread();
-
-        parkMainThread();
-        ThreadState::attachMainThread();
-    }
-
-private:
-
-    static void workerThreadMain()
-    {
-        MutexLocker locker(workerThreadMutex());
-
-        // Start up a worker thread and have it detach after the main thread has.
-        // Do this to verify that CrossThreadPersistent<>s referring to objects
-        // on one of the main thread's arenas does not upset the CTP invalidation
-        // pass that ThreadState::detach() performs.
-        ThreadState::attach();
-
-        CrossThreadPersistent<IntWrapper> persistent(IntWrapper::create(43));
-
-        // Wait for the main thread to detach.
-        wakeMainThread();
-        parkWorkerThread();
-
-        ThreadState::detach();
-        wakeMainThread();
-    }
-};
-
-TEST(HeapTest, CrossThreadPersistentOnMainThread)
-{
-    CrossThreadPersistent<IntWrapper> persistent(IntWrapper::create(42));
-    CrossThreadPersistentOnMainThreadTester::test();
-}
-
 template<typename T>
 class TraceIfNeededTester : public GarbageCollectedFinalized<TraceIfNeededTester<T>> {
 public:
diff --git a/third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp b/third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp
index 2fc1520..8412e4ed 100644
--- a/third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp
+++ b/third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp
@@ -71,6 +71,12 @@
     size_t stackRoom = stackSize - kStackRoomSize;
     RELEASE_ASSERT(stackBase > reinterpret_cast<Address>(stackRoom));
     s_stackFrameLimit = reinterpret_cast<uintptr_t>(stackBase - stackRoom);
+
+#if ENABLE(ASSERT)
+    // If current stack use is already exceeding estimated limit, mark as disabled.
+    if (!isSafeToRecurse())
+        s_isEnabled = false;
+#endif
 }
 
 size_t StackFrameDepth::getUnderestimatedStackSize()
diff --git a/third_party/WebKit/Source/platform/heap/StackFrameDepth.h b/third_party/WebKit/Source/platform/heap/StackFrameDepth.h
index 11dc1a3..05cd6c6 100644
--- a/third_party/WebKit/Source/platform/heap/StackFrameDepth.h
+++ b/third_party/WebKit/Source/platform/heap/StackFrameDepth.h
@@ -104,7 +104,8 @@
     StackFrameDepthScope()
     {
         StackFrameDepth::enableStackLimit();
-        ASSERT(StackFrameDepth::isSafeToRecurse());
+        // Enabled unless under stack pressure.
+        ASSERT(StackFrameDepth::isSafeToRecurse() || !StackFrameDepth::isEnabled());
     }
 
     ~StackFrameDepthScope()
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
index 8446223..f0d95f8d 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -203,12 +203,26 @@
 
 void ThreadState::attachMainThread()
 {
-    RELEASE_ASSERT(!Heap::s_shutdownCalled);
     MutexLocker locker(threadAttachMutex());
     ThreadState* state = new (s_mainThreadStateStorage) ThreadState();
     attachedThreads().add(state);
 }
 
+
+void ThreadState::cleanupMainThread()
+{
+    ASSERT(isMainThread());
+
+    // Finish sweeping before shutting down V8. Otherwise, some destructor
+    // may access V8 and cause crashes.
+    completeSweep();
+
+    // It is unsafe to trigger GCs after this point because some
+    // destructor may access already-detached V8 and cause crashes.
+    // Also it is useless. So we forbid GCs.
+    enterGCForbiddenScope();
+}
+
 void ThreadState::detachMainThread()
 {
     // Enter a safe point before trying to acquire threadAttachMutex
@@ -218,28 +232,23 @@
     ThreadState* state = mainThreadState();
     ASSERT(state == ThreadState::current());
     ASSERT(state->checkThread());
-    // You must call unregisterTraceDOMWrappers before detaching
-    // the main thread.
-    ASSERT(!state->m_isolate);
+    ASSERT(!state->isSweepingInProgress());
 
-    // 1. Finish sweeping.
-    state->completeSweep();
-    {
-        SafePointAwareMutexLocker locker(threadAttachMutex(), BlinkGC::NoHeapPointersOnStack);
+    // The main thread must be the last thread that gets detached.
+    RELEASE_ASSERT(ThreadState::attachedThreads().size() == 1);
 
-        // 2. Add the main thread's heap pages to the orphaned pool.
-        state->cleanupPages();
+    // Add the main thread's heap pages to the orphaned pool.
+    state->cleanupPages();
 
-        // 3. Detach the main thread.
-        ASSERT(attachedThreads().contains(state));
-        attachedThreads().remove(state);
-        state->~ThreadState();
-    }
+    // Detach the main thread. We don't need to grab a lock because
+    // the main thread should be the last thread that gets detached.
+    ASSERT(attachedThreads().contains(state));
+    attachedThreads().remove(state);
+    state->~ThreadState();
 }
 
 void ThreadState::attach()
 {
-    RELEASE_ASSERT(!Heap::s_shutdownCalled);
     MutexLocker locker(threadAttachMutex());
     ThreadState* state = new ThreadState();
     attachedThreads().add(state);
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.h b/third_party/WebKit/Source/platform/heap/ThreadState.h
index ed066d6..22a5856 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.h
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.h
@@ -190,6 +190,7 @@
 
     static void attachMainThread();
     static void detachMainThread();
+    void cleanupMainThread();
 
     // Trace all persistent roots, called when marking the managed heap objects.
     static void visitPersistentRoots(Visitor*);
@@ -430,11 +431,6 @@
         m_isolate = isolate;
         m_traceDOMWrappers = traceDOMWrappers;
     }
-    void unregisterTraceDOMWrappers()
-    {
-        m_isolate = nullptr;
-        m_traceDOMWrappers = nullptr;
-    }
 
     // By entering a gc-forbidden scope, conservative GCs will not
     // be allowed while handling an out-of-line allocation request.
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
index 75d70ed..dc92826 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
@@ -251,7 +251,7 @@
     }
 }
 
-ImagePlanes::ImagePlanes(void* planes[3], size_t rowBytes[3])
+ImagePlanes::ImagePlanes(void* planes[3], const size_t rowBytes[3])
 {
     for (int i = 0; i < 3; ++i) {
         m_planes[i] = planes[i];
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
index 2ebd7797c..518499f 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
@@ -55,7 +55,7 @@
     WTF_MAKE_NONCOPYABLE(ImagePlanes);
 public:
     ImagePlanes();
-    ImagePlanes(void* planes[3], size_t rowBytes[3]);
+    ImagePlanes(void* planes[3], const size_t rowBytes[3]);
 
     void* plane(int);
     size_t rowBytes(int) const;
@@ -71,8 +71,6 @@
 class PLATFORM_EXPORT ImageDecoder {
     WTF_MAKE_NONCOPYABLE(ImageDecoder); USING_FAST_MALLOC(ImageDecoder);
 public:
-    enum SizeType { ActualSize, SizeForMemoryAllocation };
-
     static const size_t noDecodedImageByteLimit = Platform::noDecodedImageByteLimit;
 
     enum AlphaOption {
@@ -136,9 +134,21 @@
     // return the actual decoded size.
     virtual IntSize decodedSize() const { return size(); }
 
-    // Decoders which support YUV decoding can override this to
-    // give potentially different sizes per component.
-    virtual IntSize decodedYUVSize(int component, SizeType) const { return decodedSize(); }
+    // Image decoders that support YUV decoding must override this to
+    // provide the size of each component.
+    virtual IntSize decodedYUVSize(int component) const
+    {
+        ASSERT(false);
+        return IntSize();
+    }
+
+    // Image decoders that support YUV decoding must override this to
+    // return the width of each row of the memory allocation.
+    virtual size_t decodedYUVWidthBytes(int component) const
+    {
+        ASSERT(false);
+        return 0;
+    }
 
     // This will only differ from size() for ICO (where each frame is a
     // different icon) or other formats where different frames are different
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 a423aab..11593f1 100644
--- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -233,14 +233,16 @@
 }
 #endif
 
-static IntSize computeYUVSize(const jpeg_decompress_struct* info, int component, ImageDecoder::SizeType sizeType)
+static IntSize computeYUVSize(const jpeg_decompress_struct* info, int component)
 {
-    if (sizeType == ImageDecoder::SizeForMemoryAllocation) {
-        return IntSize(info->cur_comp_info[component]->width_in_blocks * DCTSIZE, info->cur_comp_info[component]->height_in_blocks * DCTSIZE);
-    }
     return IntSize(info->cur_comp_info[component]->downsampled_width, info->cur_comp_info[component]->downsampled_height);
 }
 
+static size_t computeYUVWidthBytes(const jpeg_decompress_struct* info, int component)
+{
+    return info->cur_comp_info[component]->width_in_blocks * DCTSIZE;
+}
+
 static yuv_subsampling yuvSubsampling(const jpeg_decompress_struct& info)
 {
     if ((DCTSIZE == 8)
@@ -494,7 +496,7 @@
             if (overrideColorSpace == JCS_YCbCr) {
                 m_info.out_color_space = JCS_YCbCr;
                 m_info.raw_data_out = TRUE;
-                m_uvSize = computeYUVSize(&m_info, 1, ImageDecoder::SizeForMemoryAllocation); // U size and V size have to be the same if we got here
+                m_uvSize = computeYUVSize(&m_info, 1); // U size and V size have to be the same if we got here
             }
 
             // Don't allocate a giant and superfluous memory buffer when the
@@ -674,14 +676,18 @@
         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;
+        if (m_info.out_color_space != JCS_YCbCr)
+            return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, 4 * m_info.output_width, 1);
 
-        return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, width * 4, 1);
+        // Compute the width of the Y plane in bytes.  This may be larger than the output
+        // width, since the jpeg library requires that the allocated width be a multiple of
+        // DCTSIZE.  Note that this buffer will be used as garbage memory for rows that
+        // extend below the actual height of the image.  We can reuse the same memory for
+        // the U and V planes, since we are guaranteed that the Y plane width is at least
+        // as large as the U and V plane widths.
+        int widthBytes = computeYUVWidthBytes(&m_info, 0);
+        return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, widthBytes, 1);
     }
 
     void updateRestartPosition()
@@ -802,13 +808,22 @@
     m_decodedSize = IntSize(width, height);
 }
 
-IntSize JPEGImageDecoder::decodedYUVSize(int component, ImageDecoder::SizeType sizeType) const
+IntSize JPEGImageDecoder::decodedYUVSize(int component) const
 {
     ASSERT((component >= 0) && (component <= 2) && m_reader);
     const jpeg_decompress_struct* info = m_reader->info();
 
     ASSERT(info->out_color_space == JCS_YCbCr);
-    return computeYUVSize(info, component, sizeType);
+    return computeYUVSize(info, component);
+}
+
+size_t JPEGImageDecoder::decodedYUVWidthBytes(int component) const
+{
+    ASSERT((component >= 0) && (component <= 2) && m_reader);
+    const jpeg_decompress_struct* info = m_reader->info();
+
+    ASSERT(info->out_color_space == JCS_YCbCr);
+    return computeYUVWidthBytes(info, component);
 }
 
 unsigned JPEGImageDecoder::desiredScaleNumerator() const
@@ -913,12 +928,10 @@
     bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16)
     bufferraw[1] = &bufferraw2[16]; // U channel rows (8)
     bufferraw[2] = &bufferraw2[24]; // V channel rows (8)
-    int yWidth = info->output_width;
     int yHeight = info->output_height;
-    int yMaxH = yHeight - 1;
     int v = info->cur_comp_info[0]->v_samp_factor;
     IntSize uvSize = reader->uvSize();
-    int uvMaxH = uvSize.height() - 1;
+    int uvHeight = uvSize.height();
     JSAMPROW outputY = static_cast<JSAMPROW>(imagePlanes->plane(0));
     JSAMPROW outputU = static_cast<JSAMPROW>(imagePlanes->plane(1));
     JSAMPROW outputV = static_cast<JSAMPROW>(imagePlanes->plane(2));
@@ -928,38 +941,25 @@
 
     // Request 8 or 16 scanlines: returns 0 or more scanlines.
     int yScanlinesToRead = DCTSIZE * v;
-    JSAMPROW yLastRow = *samples;
-    JSAMPROW uLastRow = yLastRow + rowBytesY;
-    JSAMPROW vLastRow = uLastRow + rowBytesY;
-    JSAMPROW dummyRow = vLastRow + rowBytesY;
-
+    JSAMPROW dummyRow = *samples;
     while (info->output_scanline < info->output_height) {
         // Assign 8 or 16 rows of memory to read the Y channel.
-        bool hasYLastRow = false;
         for (int i = 0; i < yScanlinesToRead; ++i) {
             int scanline = info->output_scanline + i;
-            if (scanline < yMaxH) {
+            if (scanline < yHeight) {
                 bufferraw2[i] = &outputY[scanline * rowBytesY];
-            } else if (scanline == yMaxH) {
-                bufferraw2[i] = yLastRow;
-                hasYLastRow = true;
             } else {
                 bufferraw2[i] = dummyRow;
             }
         }
 
         // Assign 8 rows of memory to read the U and V channels.
-        bool hasUVLastRow = false;
         int scaledScanline = info->output_scanline / v;
         for (int i = 0; i < 8; ++i) {
             int scanline = scaledScanline + i;
-            if (scanline < uvMaxH) {
+            if (scanline < uvHeight) {
                 bufferraw2[16 + i] = &outputU[scanline * rowBytesU];
                 bufferraw2[24 + i] = &outputV[scanline * rowBytesV];
-            } else if (scanline == uvMaxH) {
-                bufferraw2[16 + i] = uLastRow;
-                bufferraw2[24 + i] = vLastRow;
-                hasUVLastRow = true;
             } else {
                 bufferraw2[16 + i] = dummyRow;
                 bufferraw2[24 + i] = dummyRow;
@@ -969,14 +969,6 @@
         JDIMENSION scanlinesRead = jpeg_read_raw_data(info, bufferraw, yScanlinesToRead);
         if (!scanlinesRead)
             return false;
-
-        if (hasYLastRow)
-            memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth);
-
-        if (hasUVLastRow) {
-            memcpy(&outputU[uvMaxH * rowBytesU], uLastRow, uvSize.width());
-            memcpy(&outputV[uvMaxH * rowBytesV], vLastRow, uvSize.width());
-        }
     }
 
     info->output_scanline = std::min(info->output_scanline, info->output_height);
diff --git a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.h
index 25aa80a..a092d495 100644
--- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.h
@@ -43,8 +43,9 @@
     void onSetData(SharedBuffer* data) override;
     bool hasColorProfile() const override { return m_hasColorProfile; }
     IntSize decodedSize() const override { return m_decodedSize; }
-    IntSize decodedYUVSize(int component, SizeType) const override;
     bool setSize(unsigned width, unsigned height) override;
+    IntSize decodedYUVSize(int component) const override;
+    size_t decodedYUVWidthBytes(int component) const override;
     bool canDecodeToYUV() override;
     bool decodeToYUV() override;
     void setImagePlanes(PassOwnPtr<ImagePlanes>) override;
diff --git a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoderTest.cpp b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoderTest.cpp
index 9f2c660..305989a 100644
--- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoderTest.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoderTest.cpp
@@ -36,6 +36,7 @@
 #include "public/platform/WebData.h"
 #include "public/platform/WebSize.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "wtf/ArrayBuffer.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
 
@@ -80,15 +81,17 @@
     OwnPtr<ImageDecoder> decoder = createDecoder(maxDecodedBytes);
     decoder->setData(data.get(), true);
 
-    OwnPtr<ImagePlanes> imagePlanes = adoptPtr(new ImagePlanes());
-    decoder->setImagePlanes(imagePlanes.release());
+    // Setting a dummy ImagePlanes object signals to the decoder that we want to do YUV decoding.
+    OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes());
+    decoder->setImagePlanes(dummyImagePlanes.release());
+
     bool sizeIsAvailable = decoder->isSizeAvailable();
     ASSERT_TRUE(sizeIsAvailable);
 
     IntSize size = decoder->decodedSize();
-    IntSize ySize = decoder->decodedYUVSize(0, ImageDecoder::ActualSize);
-    IntSize uSize = decoder->decodedYUVSize(1, ImageDecoder::ActualSize);
-    IntSize vSize = decoder->decodedYUVSize(2, ImageDecoder::ActualSize);
+    IntSize ySize = decoder->decodedYUVSize(0);
+    IntSize uSize = decoder->decodedYUVSize(1);
+    IntSize vSize = decoder->decodedYUVSize(2);
 
     ASSERT_TRUE(size.width() == ySize.width());
     ASSERT_TRUE(size.height() == ySize.height());
@@ -99,6 +102,22 @@
     *outputYHeight = ySize.height();
     *outputUVWidth = uSize.width();
     *outputUVHeight = uSize.height();
+
+    size_t rowBytes[3];
+    rowBytes[0] = decoder->decodedYUVWidthBytes(0);
+    rowBytes[1] = decoder->decodedYUVWidthBytes(1);
+    rowBytes[2] = decoder->decodedYUVWidthBytes(2);
+
+    RefPtr<ArrayBuffer> buffer(ArrayBuffer::create(rowBytes[0] * ySize.height() + rowBytes[1] * uSize.height() + rowBytes[2] * vSize.height(), 1));
+    void* planes[3];
+    planes[0] = buffer->data();
+    planes[1] = ((char*) planes[0]) + rowBytes[0] * ySize.height();
+    planes[2] = ((char*) planes[1]) + rowBytes[1] * uSize.height();
+
+    OwnPtr<ImagePlanes> imagePlanes = adoptPtr(new ImagePlanes(planes, rowBytes));
+    decoder->setImagePlanes(imagePlanes.release());
+
+    ASSERT_TRUE(decoder->decodeToYUV());
 }
 
 // Tests failure on a too big image.
@@ -216,6 +235,13 @@
     EXPECT_EQ(128u, outputUVWidth);
     EXPECT_EQ(128u, outputUVHeight);
 
+    const char* jpegFileImageSizeNotMultipleOf8 = "/LayoutTests/fast/images/resources/cropped_mandrill.jpg"; // 439x154
+    readYUV(LargeEnoughSize, &outputYWidth, &outputYHeight, &outputUVWidth, &outputUVHeight, jpegFileImageSizeNotMultipleOf8);
+    EXPECT_EQ(439u, outputYWidth);
+    EXPECT_EQ(154u, outputYHeight);
+    EXPECT_EQ(220u, outputUVWidth);
+    EXPECT_EQ(77u, outputUVHeight);
+
     // Make sure we revert to RGBA decoding when we're about to downscale,
     // which can occur on memory-constrained android devices.
     RefPtr<SharedBuffer> data = readFile(jpegFile);
diff --git a/third_party/WebKit/Source/platform/platform_generated.gyp b/third_party/WebKit/Source/platform/platform_generated.gyp
index 9b6f6558..0d6530b 100644
--- a/third_party/WebKit/Source/platform/platform_generated.gyp
+++ b/third_party/WebKit/Source/platform/platform_generated.gyp
@@ -139,25 +139,25 @@
           ],
         },
         {
-          'action_name': 'CharacterData',
+          'action_name': 'CharacterPropertyData',
           'inputs': [
-            'fonts/CharacterDataGenerator.cpp',
-            'fonts/CharacterData.h'
+            'fonts/CharacterPropertyDataGenerator.cpp',
+            'fonts/CharacterPropertyDataGenerator.h'
           ],
           'outputs': [
-            '<(blink_platform_output_dir)/CharacterData.cpp',
+            '<(blink_platform_output_dir)/CharacterPropertyData.cpp',
           ],
           'conditions': [
             ['generate_character_data==1', {
               'action': [
                 '<(PRODUCT_DIR)/character_data_generator',
-                '<(blink_platform_output_dir)/CharacterData.cpp',
+                '<(blink_platform_output_dir)/CharacterPropertyData.cpp',
               ],
             }, {
               'action': [
                 'cp',
-                'fonts/CharacterData.cpp',
-                '<(blink_platform_output_dir)/CharacterData.cpp',
+                'fonts/CharacterPropertyData.cpp',
+                '<(blink_platform_output_dir)/CharacterPropertyData.cpp',
               ],
             }]
           ],
@@ -169,7 +169,7 @@
       'type': 'executable',
       'toolsets': ['host'],
       'sources': [
-        'fonts/CharacterDataGenerator.cpp',
+        'fonts/CharacterPropertyDataGenerator.cpp',
       ],
       'dependencies': [
         '<(DEPTH)/third_party/icu/icu.gyp:icuuc#host',
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp b/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp
index 4633bc4..ee962d9a 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp
@@ -75,26 +75,22 @@
 
 class ScrollableAreaTest : public testing::Test {
 public:
-    ScrollableAreaTest() : m_oldPlatform(nullptr) { }
+    ScrollableAreaTest() { }
 
     void SetUp() override
     {
-        m_oldPlatform = Platform::current();
         TestingPlatformSupport::Config config;
-        config.compositorSupport = m_oldPlatform->compositorSupport();
+        config.compositorSupport = Platform::current()->compositorSupport();
         m_fakePlatform = adoptPtr(new TestingPlatformSupportWithMockScheduler(config));
-        Platform::initialize(m_fakePlatform.get());
     }
 
     void TearDown() override
     {
-        Platform::initialize(m_oldPlatform);
         m_fakePlatform = nullptr;
     }
 
 private:
     OwnPtr<TestingPlatformSupportWithMockScheduler> m_fakePlatform;
-    Platform* m_oldPlatform; // Not owned.
 };
 
 TEST_F(ScrollableAreaTest, ScrollAnimatorCurrentPositionShouldBeSync)
diff --git a/third_party/WebKit/Source/platform/testing/RunAllTests.cpp b/third_party/WebKit/Source/platform/testing/RunAllTests.cpp
index 69caa0039..dc8ed0f 100644
--- a/third_party/WebKit/Source/platform/testing/RunAllTests.cpp
+++ b/third_party/WebKit/Source/platform/testing/RunAllTests.cpp
@@ -35,6 +35,7 @@
 #include "platform/HTTPNames.h"
 #include "platform/heap/Heap.h"
 #include "platform/testing/TestingPlatformSupport.h"
+#include "public/platform/Platform.h"
 #include "wtf/CryptographicallyRandomNumber.h"
 #include "wtf/CurrentTime.h"
 #include "wtf/MainThread.h"
@@ -61,6 +62,11 @@
     return result;
 }
 
+class DummyPlatform final : public blink::Platform {
+public:
+    DummyPlatform() { }
+};
+
 } // namespace
 
 int main(int argc, char** argv)
@@ -71,30 +77,35 @@
     WTF::setTimeFunctionsForTesting(dummyCurrentTime);
     WTF::initialize(nullptr);
     WTF::initializeMainThread(0);
+    int result = 0;
+    {
+        OwnPtr<DummyPlatform> platform = adoptPtr(new DummyPlatform);
+        blink::Platform::initialize(platform.get());
+        {
+            blink::TestingPlatformSupport::Config platformConfig;
+            cc_blink::WebCompositorSupportImpl compositorSupport;
+            platformConfig.compositorSupport = &compositorSupport;
+            blink::TestingPlatformSupport platform(platformConfig);
 
-    blink::TestingPlatformSupport::Config platformConfig;
-    cc_blink::WebCompositorSupportImpl compositorSupport;
-    platformConfig.compositorSupport = &compositorSupport;
-    blink::TestingPlatformSupport platform(platformConfig);
+            blink::Heap::init();
+            blink::ThreadState::attachMainThread();
+            blink::ThreadState::current()->registerTraceDOMWrappers(nullptr, nullptr);
+            blink::EventTracer::initialize();
 
-    blink::Heap::init();
-    blink::ThreadState::attachMainThread();
-    blink::ThreadState::current()->registerTraceDOMWrappers(nullptr, nullptr);
-    blink::EventTracer::initialize();
+            blink::HTTPNames::init();
 
-    blink::HTTPNames::init();
+            base::TestSuite testSuite(argc, argv);
 
-    base::TestSuite testSuite(argc, argv);
+            mojo::edk::Init();
+            base::TestIOThread testIoThread(base::TestIOThread::kAutoStart);
+            WTF::OwnPtr<mojo::edk::test::ScopedIPCSupport> ipcSupport(adoptPtr(new mojo::edk::test::ScopedIPCSupport(testIoThread.task_runner())));
+            result = base::LaunchUnitTests(argc, argv, base::Bind(runTestSuite, base::Unretained(&testSuite)));
 
-    mojo::edk::Init();
-    base::TestIOThread testIoThread(base::TestIOThread::kAutoStart);
-    WTF::OwnPtr<mojo::edk::test::ScopedIPCSupport> ipcSupport(
-        adoptPtr(new mojo::edk::test::ScopedIPCSupport(testIoThread.task_runner())));
-
-    int result = base::LaunchUnitTests(argc, argv, base::Bind(runTestSuite, base::Unretained(&testSuite)));
-
-    blink::ThreadState::detachMainThread();
-    blink::Heap::shutdown();
+            blink::ThreadState::detachMainThread();
+            blink::Heap::shutdown();
+        }
+        blink::Platform::shutdown();
+    }
 
     WTF::shutdown();
     WTF::Partitions::shutdown();
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
index fe86449..f187bc60 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
@@ -82,12 +82,13 @@
     : m_config(config)
     , m_oldPlatform(Platform::current())
 {
-    Platform::initialize(this);
+    ASSERT(m_oldPlatform);
+    Platform::setCurrentPlatformForTesting(this);
 }
 
 TestingPlatformSupport::~TestingPlatformSupport()
 {
-    Platform::initialize(m_oldPlatform);
+    Platform::setCurrentPlatformForTesting(m_oldPlatform);
 }
 
 WebDiscardableMemory* TestingPlatformSupport::allocateAndLockDiscardableMemory(size_t bytes)
diff --git a/third_party/WebKit/Source/web/WebAXObject.cpp b/third_party/WebKit/Source/web/WebAXObject.cpp
index ca85de8..b892249 100644
--- a/third_party/WebKit/Source/web/WebAXObject.cpp
+++ b/third_party/WebKit/Source/web/WebAXObject.cpp
@@ -124,7 +124,7 @@
 {
     if (!isDetached()) {
         Document* document = m_private->getDocument();
-        if (!document || !document->topDocument().view())
+        if (!document || !document->view())
             return false;
         document->view()->updateAllLifecyclePhases();
     }
diff --git a/third_party/WebKit/Source/web/WebKit.cpp b/third_party/WebKit/Source/web/WebKit.cpp
index 4921ba561..73141c0 100644
--- a/third_party/WebKit/Source/web/WebKit.cpp
+++ b/third_party/WebKit/Source/web/WebKit.cpp
@@ -184,6 +184,8 @@
     }
 #endif
 
+    ThreadState::current()->cleanupMainThread();
+
     // currentThread() is null if we are running on a thread without a message loop.
     if (Platform::current()->currentThread()) {
         Platform::current()->unregisterMemoryDumpProvider(WebCacheMemoryDumpProvider::instance());
diff --git a/third_party/WebKit/Source/web/tests/TopControlsTest.cpp b/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
index cdfd26de1..f8b02f28 100644
--- a/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
+++ b/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
@@ -167,7 +167,7 @@
     EXPECT_FLOAT_EQ(25.f, webView->topControls().contentOffset());
     EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollPosition());
 
-    // Top controls should consume 30px and become hidden. Excess scroll should be consumed by the page.
+    // Top controls should consume 25px and become hidden. Excess scroll should be consumed by the page.
     webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -40.f));
     EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
     EXPECT_POINT_EQ(IntPoint(0, 15), frame()->view()->scrollPosition());
diff --git a/third_party/WebKit/Source/wtf/TypeTraits.h b/third_party/WebKit/Source/wtf/TypeTraits.h
index d3ef548..c6a05230 100644
--- a/third_party/WebKit/Source/wtf/TypeTraits.h
+++ b/third_party/WebKit/Source/wtf/TypeTraits.h
@@ -48,19 +48,71 @@
     WeakHandlingInCollections
 };
 
+// Compilers behave differently on __has_trivial_assign(T) if T has a user-deleted copy assignment operator:
+//
+//     * MSVC returns false; but
+//     * The others return true.
+//
+// To workaround that, here we have IsAssignable<T, From> class template, but unfortunately, MSVC 2013 cannot compile
+// it due to the lack of expression SFINAE.
+//
+// Thus, IsAssignable is only defined on non-MSVC compilers.
+#if !COMPILER(MSVC) || COMPILER(CLANG)
+template <typename T, typename From>
+class IsAssignable {
+    typedef char YesType;
+    struct NoType {
+        char padding[8];
+    };
+
+    template <typename T2, typename From2, typename = decltype(std::declval<T2>() = std::declval<From2>())>
+    static YesType checkAssignability(int);
+    template <typename T2, typename From2>
+    static NoType checkAssignability(...);
+
+public:
+    static const bool value = sizeof(checkAssignability<T, From>(0)) == sizeof(YesType);
+};
+
+template <typename T>
+struct IsCopyAssignable {
+    static_assert(!std::is_reference<T>::value, "T must not be a reference.");
+    static const bool value = IsAssignable<T, const T&>::value;
+};
+
+template <typename T>
+struct IsMoveAssignable {
+    static_assert(!std::is_reference<T>::value, "T must not be a reference.");
+    static const bool value = IsAssignable<T, T&&>::value;
+};
+#endif // !COMPILER(MSVC) || COMPILER(CLANG)
+
 template <typename T> struct IsTriviallyCopyAssignable {
+#if COMPILER(MSVC) && !COMPILER(CLANG)
     static const bool value = __has_trivial_assign(T);
+#else
+    static const bool value = __has_trivial_assign(T) && IsCopyAssignable<T>::value;
+#endif
 };
 
 template <typename T> struct IsTriviallyMoveAssignable {
-    static const bool value = __has_trivial_assign(T);
+    // TODO(yutak): This isn't really correct, because __has_trivial_assign appears to look only at copy assignment.
+    // However, std::is_trivially_move_assignable isn't available at this moment, and there isn't a good way to
+    // write that ourselves.
+    //
+    // Here we use IsTriviallyCopyAssignable as a conservative approximation: if T is trivially copy assignable,
+    // T is trivially move assignable, too. This definition misses a case where T is trivially move-only assignable,
+    // but such cases should be rare.
+    static const bool value = IsTriviallyCopyAssignable<T>::value;
 };
 
 template <typename T> struct IsTriviallyDefaultConstructible {
+    // TODO(yutak): Below has the same issue as crbug.com/592767.
     static const bool value = __has_trivial_constructor(T);
 };
 
 template <typename T> struct IsTriviallyDestructible {
+    // TODO(yutak): Ditto.
     static const bool value = __has_trivial_destructor(T);
 };
 
diff --git a/third_party/WebKit/Source/wtf/TypeTraitsTest.cpp b/third_party/WebKit/Source/wtf/TypeTraitsTest.cpp
index 12fec33..79fddfc 100644
--- a/third_party/WebKit/Source/wtf/TypeTraitsTest.cpp
+++ b/third_party/WebKit/Source/wtf/TypeTraitsTest.cpp
@@ -103,6 +103,67 @@
 typedef int IntArray[];
 typedef int IntArraySized[4];
 
+#if !COMPILER(MSVC) || COMPILER(CLANG)
+
+class AssignmentDeleted final {
+private:
+    AssignmentDeleted& operator=(const AssignmentDeleted&) = delete;
+};
+
+static_assert(!IsCopyAssignable<AssignmentDeleted>::value, "AssignmentDeleted isn't copy assignable.");
+static_assert(!IsMoveAssignable<AssignmentDeleted>::value, "AssignmentDeleted isn't move assignable.");
+
+class AssignmentPrivate final {
+private:
+    AssignmentPrivate& operator=(const AssignmentPrivate&);
+};
+
+static_assert(!IsCopyAssignable<AssignmentPrivate>::value, "AssignmentPrivate isn't copy assignable.");
+static_assert(!IsMoveAssignable<AssignmentPrivate>::value, "AssignmentPrivate isn't move assignable.");
+
+class CopyAssignmentDeleted final {
+public:
+    CopyAssignmentDeleted& operator=(CopyAssignmentDeleted&&);
+private:
+    CopyAssignmentDeleted& operator=(const CopyAssignmentDeleted&) = delete;
+};
+
+static_assert(!IsCopyAssignable<CopyAssignmentDeleted>::value, "CopyAssignmentDeleted isn't copy assignable.");
+static_assert(IsMoveAssignable<CopyAssignmentDeleted>::value, "CopyAssignmentDeleted is move assignable.");
+
+class CopyAssignmentPrivate final {
+public:
+    CopyAssignmentPrivate& operator=(CopyAssignmentPrivate&&);
+private:
+    CopyAssignmentPrivate& operator=(const CopyAssignmentPrivate&);
+};
+
+static_assert(!IsCopyAssignable<CopyAssignmentPrivate>::value, "CopyAssignmentPrivate isn't copy assignable.");
+static_assert(IsMoveAssignable<CopyAssignmentPrivate>::value, "CopyAssignmentPrivate is move assignable.");
+
+class CopyAssignmentUndeclared final {
+public:
+    CopyAssignmentUndeclared& operator=(CopyAssignmentUndeclared&&);
+};
+
+static_assert(!IsCopyAssignable<CopyAssignmentUndeclared>::value, "CopyAssignmentUndeclared isn't copy assignable.");
+static_assert(IsMoveAssignable<CopyAssignmentUndeclared>::value, "CopyAssignmentUndeclared is move assignable.");
+
+class Assignable final {
+public:
+    Assignable& operator=(const Assignable&);
+};
+
+static_assert(IsCopyAssignable<Assignable>::value, "Assignable is copy assignable.");
+static_assert(IsMoveAssignable<Assignable>::value, "Assignable is move assignable.");
+
+class AssignableImplicit final { };
+
+static_assert(IsCopyAssignable<AssignableImplicit>::value, "AssignableImplicit is copy assignable.");
+static_assert(IsMoveAssignable<AssignableImplicit>::value, "AssignableImplicit is move assignable.");
+
+#endif // !COMPILER(MSVC) || COMPILER(CLANG)
+
 } // anonymous namespace
 
 } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/VectorTest.cpp b/third_party/WebKit/Source/wtf/VectorTest.cpp
index d06b47b..447edd0 100644
--- a/third_party/WebKit/Source/wtf/VectorTest.cpp
+++ b/third_party/WebKit/Source/wtf/VectorTest.cpp
@@ -459,6 +459,31 @@
         vector.append(const_cast<const WTF::String&>(vector.first()));
 }
 
+// The test below is for the following issue:
+//
+// https://bugs.chromium.org/p/chromium/issues/detail?id=592767
+//
+// where deleted copy assignment operator made canMoveWithMemcpy true because of the implementation of
+// IsTriviallyMoveAssignable<T>.
+
+class MojoMoveOnlyType final {
+public:
+    MojoMoveOnlyType();
+    MojoMoveOnlyType(MojoMoveOnlyType&&);
+    MojoMoveOnlyType& operator=(MojoMoveOnlyType&&);
+    ~MojoMoveOnlyType();
+
+private:
+    MojoMoveOnlyType(const MojoMoveOnlyType&) = delete;
+    void operator=(const MojoMoveOnlyType&) = delete;
+};
+
+static_assert(!IsTriviallyMoveAssignable<MojoMoveOnlyType>::value, "MojoMoveOnlyType isn't trivially move assignable.");
+static_assert(!IsTriviallyCopyAssignable<MojoMoveOnlyType>::value, "MojoMoveOnlyType isn't trivially copy assignable.");
+
+static_assert(!VectorTraits<MojoMoveOnlyType>::canMoveWithMemcpy, "MojoMoveOnlyType can't be moved with memcpy.");
+static_assert(!VectorTraits<MojoMoveOnlyType>::canCopyWithMemcpy, "MojoMoveOnlyType can't be copied with memcpy.");
+
 } // anonymous namespace
 
 } // namespace WTF
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h
index 30192bf..880be7b 100644
--- a/third_party/WebKit/public/platform/Platform.h
+++ b/third_party/WebKit/public/platform/Platform.h
@@ -120,6 +120,7 @@
 class WebTrialTokenValidator;
 class WebURL;
 class WebURLLoader;
+class WebURLResponse;
 class WebUnitTestSupport;
 struct WebLocalizedString;
 struct WebSize;
@@ -138,6 +139,9 @@
     static void shutdown();
     static Platform* current();
 
+    // Used to switch the current platform only for testing.
+    static void setCurrentPlatformForTesting(Platform*);
+
     // May return null.
     virtual WebCookieJar* cookieJar() { return nullptr; }
 
@@ -322,6 +326,10 @@
 
     virtual bool portAllowed(const WebURL&) const { return false; }
 
+    // Returns true and stores the position of the end of the headers to |*end|
+    // if the headers part ends in |bytes[0..size]|. Returns false otherwise.
+    virtual bool parseMultipartHeadersFromBody(const char* bytes, size_t /* size */, WebURLResponse*, size_t* end) const { return false; }
+
     // Plugins -------------------------------------------------------------
 
     // If refresh is true, then cached information should not be used to
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index 691b905..3bb727b 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -36,3 +36,5 @@
 
 Local Modifications:
 - Move bit_cast from base/macros.h to its own header.
+- Replace base/template_util.h with C++11 type_traits.
+- Add std::is_same into compat/non_cxx11_lib/type_traits.
diff --git a/third_party/crashpad/crashpad/compat/non_cxx11_lib/type_traits b/third_party/crashpad/crashpad/compat/non_cxx11_lib/type_traits
index 9f11fd4a..e56c220 100644
--- a/third_party/crashpad/crashpad/compat/non_cxx11_lib/type_traits
+++ b/third_party/crashpad/crashpad/compat/non_cxx11_lib/type_traits
@@ -30,6 +30,11 @@
 template <class T>
 struct remove_reference<T&> { using type = T; };
 
+template <typename T, typename S>
+struct is_same { enum { value = false }; };
+template <typename T>
+struct is_same<T, T> { enum { value = true }; };
+
 }  // namespace std
 
 #endif  // CXX_LIBRARY_VERSION
diff --git a/third_party/crashpad/crashpad/util/win/process_info.cc b/third_party/crashpad/crashpad/util/win/process_info.cc
index 5628e04..9e47206d 100644
--- a/third_party/crashpad/crashpad/util/win/process_info.cc
+++ b/third_party/crashpad/crashpad/util/win/process_info.cc
@@ -18,11 +18,11 @@
 
 #include <algorithm>
 #include <limits>
+#include <type_traits>
 
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/stringprintf.h"
-#include "base/template_util.h"
 #include "build/build_config.h"
 #include "util/numeric/safe_assignment.h"
 #include "util/win/get_function.h"
@@ -636,9 +636,9 @@
   // Find all the ranges that overlap the target range, maintaining their order.
   ProcessInfo::MemoryBasicInformation64Vector overlapping;
   for (const auto& mi : memory_info) {
-    static_assert(base::is_same<decltype(mi.BaseAddress), WinVMAddress>::value,
+    static_assert(std::is_same<decltype(mi.BaseAddress), WinVMAddress>::value,
                   "expected range address to be WinVMAddress");
-    static_assert(base::is_same<decltype(mi.RegionSize), WinVMSize>::value,
+    static_assert(std::is_same<decltype(mi.RegionSize), WinVMSize>::value,
                   "expected range size to be WinVMSize");
     if (range.OverlapsRange(Range(mi.BaseAddress, mi.RegionSize)))
       overlapping.push_back(mi);
diff --git a/tools/android/loading/gce/README.md b/tools/android/loading/gce/README.md
new file mode 100644
index 0000000..eda5520
--- /dev/null
+++ b/tools/android/loading/gce/README.md
@@ -0,0 +1,132 @@
+# Clovis in the Cloud: Developer Guide
+
+This document describes how to collect Chromium traces using Google Compute
+Engine.
+
+[TOC]
+
+## Initial setup
+
+Install the [gcloud command line tool][1].
+
+Checkout the source:
+
+```shell
+mkdir clovis
+cd clovis
+gcloud init
+```
+
+When offered, accept to clone the Google Cloud repo.
+
+## Update or Change the code
+
+Make changes to the code, or simply copy the latest version from Chromium into
+your local Google Cloud repository. Then commit and push:
+
+```shell
+git commit
+git push -u origin master
+```
+
+If there are instances already running, they need to be restarted for this to
+take effect.
+
+## Start the app in the cloud
+
+Create an instance using latest ubuntu LTS:
+
+```shell
+gcloud compute instances create clovis-tracer-1 \
+ --machine-type n1-standard-1 \
+ --image ubuntu-14-04 \
+ --zone europe-west1-c \
+ --tags clovis-http-server \
+ --scopes cloud-platform \
+ --metadata-from-file startup-script=default/startup-script.sh
+```
+
+This should output the IP address of the instance.
+Otherwise the IP address can be retrieved by doing:
+
+```shell
+gcloud compute instances list
+```
+
+Interact with the app on the port 8080 in your browser at
+`http://<instance-ip>:8080`.
+
+TODO: allow starting the instance in the cloud without Supervisor. This enables
+iterative development on the instance using SSH, manually starting and stopping
+the app. This can be done using [instance metadata][2].
+
+## Stop the app in the cloud
+
+```shell
+gcloud compute instances delete clovis-tracer-1
+```
+
+## Connect to the instance with SSH
+
+```shell
+gcloud compute ssh clovis-tracer-1
+```
+
+## Use the app locally
+
+Setup the local environment:
+
+```shell
+virtualenv env
+source env/bin/activate
+pip install -r pip_requirements.txt
+```
+
+Launch the app:
+
+```shell
+gunicorn --workers=2 main:app --bind 127.0.0.1:8000
+```
+
+In your browser, go to `http://localhost:8000` and use the app.
+
+Tear down the local environment:
+
+```shell
+deactivate
+```
+
+## Project-wide settings
+
+This is already setup, no need to do this again.
+Kept here for reference.
+
+### Server configuration file
+
+`main.py` expects to find a `server_config.json` file, which is a dictionary
+with the keys:
+
+*   `project_name`: the name of the Google Compute project,
+*   `bucket_name`: the name of the Google Storage bucket used to store the
+    results.
+
+### Firewall rule
+
+Firewall rule to allow access to the instance HTTP server from the outside:
+
+```shell
+gcloud compute firewall-rules create default-allow-http-8080 \
+    --allow tcp:8080 \
+    --source-ranges 0.0.0.0/0 \
+    --target-tags clovis-http-server \
+    --description "Allow port 8080 access to http-server"
+```
+
+The firewall rule can be disabled with:
+
+```shell
+gcloud compute firewall-rules delete default-allow-http-8080
+```
+
+[1]: https://cloud.google.com/sdk
+[2]: https://cloud.google.com/compute/docs/startupscript#custom
diff --git a/tools/android/loading/gce/main.py b/tools/android/loading/gce/main.py
new file mode 100644
index 0000000..67fe3d1
--- /dev/null
+++ b/tools/android/loading/gce/main.py
@@ -0,0 +1,87 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import json
+
+from gcloud import storage
+from gcloud.exceptions import NotFound
+from oauth2client.client import GoogleCredentials
+
+class ServerApp(object):
+  """Simple web server application, collecting traces and writing them in
+  Google Cloud Storage.
+  """
+
+  def __init__(self):
+    print 'Initializing credentials'
+    self._credentials = GoogleCredentials.get_application_default()
+    print 'Reading server configuration'
+    with open('server_config.json') as configuration_file:
+       self._config = json.load(configuration_file)
+
+  def _GetStorageClient(self):
+    return storage.Client(project = self._config['project_name'],
+                          credentials = self._credentials)
+
+  def _GetStorageBucket(self, storage_client):
+    return storage_client.get_bucket(self._config['bucket_name'])
+
+  def _UploadFile(self, file_stream, filename):
+    client = self._GetStorageClient()
+    bucket = self._GetStorageBucket(client)
+    blob = bucket.blob(filename)
+    blob.upload_from_string(file_stream)
+    url = blob.public_url
+    return url
+
+  def _DeleteFile(self, filename):
+    client = self._GetStorageClient()
+    bucket = self._GetStorageBucket(client)
+    try:
+      bucket.delete_blob(filename)
+      return True
+    except NotFound:
+      return False
+
+  def _ReadFile(self, filename):
+    client = self._GetStorageClient()
+    bucket = self._GetStorageBucket(client)
+    blob = bucket.get_blob(filename)
+    if not blob:
+      return None
+    return blob.download_as_string()
+
+  def __call__(self, environ, start_response):
+    path = environ['PATH_INFO']
+    if path == '/favicon.ico':
+        start_response('404 NOT FOUND', [('Content-Length', '0')])
+        return iter([''])
+
+    status = '200 OK'
+
+    if path == '/write':
+      url = self._UploadFile('foo', 'test.txt')
+      data = 'Writing file at\n' + url + '\n'
+    elif path == '/read':
+      data = self._ReadFile('test.txt')
+      if not data:
+        data = ''
+        status = '404 NOT FOUND'
+    elif path == '/delete':
+      if self._DeleteFile('test.txt'):
+        data = 'Success\n'
+      else:
+        data = 'Failed\n'
+    else:
+      data = environ['PATH_INFO'] + '\n'
+
+    response_headers = [
+        ('Content-type','text/plain'),
+        ('Content-Length', str(len(data)))
+    ]
+    start_response(status, response_headers)
+    return iter([data])
+
+
+app = ServerApp()
diff --git a/tools/android/loading/gce/pip_requirements.txt b/tools/android/loading/gce/pip_requirements.txt
new file mode 100644
index 0000000..e2d68b7
--- /dev/null
+++ b/tools/android/loading/gce/pip_requirements.txt
@@ -0,0 +1,2 @@
+gunicorn==19.4.5
+gcloud==0.10.1
diff --git a/tools/android/loading/gce/startup-script.sh b/tools/android/loading/gce/startup-script.sh
new file mode 100644
index 0000000..4f2cafa
--- /dev/null
+++ b/tools/android/loading/gce/startup-script.sh
@@ -0,0 +1,58 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Script executed at instance startup. It installs the required dependencies,
+# downloads the source code, and starts a web server.
+
+set -v
+
+# Talk to the metadata server to get the project id
+PROJECTID=$(curl -s \
+    "http://metadata.google.internal/computeMetadata/v1/project/project-id" \
+    -H "Metadata-Flavor: Google")
+
+# Install dependencies from apt
+apt-get update
+apt-get install -yq git supervisor python-pip python-dev libffi-dev libssl-dev
+
+# Create a pythonapp user. The application will run as this user.
+useradd -m -d /home/pythonapp pythonapp
+
+# pip from apt is out of date, so make it update itself and install virtualenv.
+pip install --upgrade pip virtualenv
+
+# Get the source code from the Google Cloud Repository
+# git requires $HOME and it's not set during the startup script.
+export HOME=/root
+git config --global credential.helper gcloud.sh
+git clone https://source.developers.google.com/p/$PROJECTID /opt/app/clovis
+
+# Install app dependencies
+virtualenv /opt/app/clovis/env
+/opt/app/clovis/env/bin/pip install -r /opt/app/clovis/pip_requirements.txt
+
+# Make sure the pythonapp user owns the application code
+chown -R pythonapp:pythonapp /opt/app
+
+# Configure supervisor to start gunicorn inside of our virtualenv and run the
+# applicaiton.
+cat >/etc/supervisor/conf.d/python-app.conf << EOF
+[program:pythonapp]
+directory=/opt/app/clovis
+command=/opt/app/clovis/env/bin/gunicorn --workers=2 main:app \
+  --bind 0.0.0.0:8080
+autostart=true
+autorestart=true
+user=pythonapp
+# Environment variables ensure that the application runs inside of the
+# configured virtualenv.
+environment=VIRTUAL_ENV="/opt/app/env/clovis",PATH="/opt/app/clovis/env/bin",\
+    HOME="/home/pythonapp",USER="pythonapp"
+stdout_logfile=syslog
+stderr_logfile=syslog
+EOF
+
+supervisorctl reread
+supervisorctl update
+
diff --git a/tools/clang/plugins/CMakeLists.txt b/tools/clang/plugins/CMakeLists.txt
index 6be8b2eb..04de853e 100644
--- a/tools/clang/plugins/CMakeLists.txt
+++ b/tools/clang/plugins/CMakeLists.txt
@@ -1,8 +1,7 @@
 set(plugin_sources
   ChromeClassTester.cpp
   FindBadConstructsAction.cpp
-  FindBadConstructsConsumer.cpp
-  CheckIPCVisitor.cpp)
+  FindBadConstructsConsumer.cpp)
 
 if(WIN32)
   # Clang doesn't support loadable modules on Windows. Unfortunately, building
diff --git a/tools/clang/plugins/CheckIPCVisitor.cpp b/tools/clang/plugins/CheckIPCVisitor.cpp
deleted file mode 100644
index b123b01..0000000
--- a/tools/clang/plugins/CheckIPCVisitor.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "CheckIPCVisitor.h"
-
-using namespace clang;
-
-namespace chrome_checker {
-
-namespace {
-
-const char kWriteParamBadType[] =
-    "[chromium-ipc] IPC::WriteParam() is called on blacklisted type '%0'%1.";
-
-const char kTupleBadType[] =
-    "[chromium-ipc] IPC tuple references banned type '%0'%1.";
-
-const char kWriteParamBadSignature[] =
-    "[chromium-ipc] IPC::WriteParam() is expected to have two arguments.";
-
-const char kNoteSeeHere[] =
-    "see here";
-
-}  // namespace
-
-CheckIPCVisitor::CheckIPCVisitor(CompilerInstance& compiler)
-  : compiler_(compiler), context_(nullptr) {
-  auto& diagnostics = compiler_.getDiagnostics();
-  error_write_param_bad_type_ = diagnostics.getCustomDiagID(
-      DiagnosticsEngine::Error, kWriteParamBadType);
-  error_tuple_bad_type_ = diagnostics.getCustomDiagID(
-      DiagnosticsEngine::Error, kTupleBadType);
-  error_write_param_bad_signature_ = diagnostics.getCustomDiagID(
-      DiagnosticsEngine::Error, kWriteParamBadSignature);
-  note_see_here_ = diagnostics.getCustomDiagID(
-      DiagnosticsEngine::Note, kNoteSeeHere);
-
-  blacklisted_typedefs_ = llvm::StringSet<>({
-      "intmax_t",
-      "uintmax_t",
-      "intptr_t",
-      "uintptr_t",
-      "wint_t",
-      "size_t",
-      "rsize_t",
-      "ssize_t",
-      "ptrdiff_t",
-      "dev_t",
-      "off_t",
-      "clock_t",
-      "time_t",
-      "suseconds_t"
-  });
-}
-
-void CheckIPCVisitor::BeginDecl(Decl* decl) {
-  decl_stack_.push_back(decl);
-}
-
-void CheckIPCVisitor::EndDecl() {
-  decl_stack_.pop_back();
-}
-
-void CheckIPCVisitor::VisitTemplateSpecializationType(
-    TemplateSpecializationType* spec) {
-  ValidateCheckedTuple(spec);
-}
-
-void CheckIPCVisitor::VisitCallExpr(CallExpr* call_expr) {
-  ValidateWriteParam(call_expr);
-}
-
-bool CheckIPCVisitor::ValidateWriteParam(const CallExpr* call_expr) {
-  const FunctionDecl* callee_decl = call_expr->getDirectCallee();
-  if (!callee_decl ||
-      callee_decl->getQualifiedNameAsString() != "IPC::WriteParam") {
-    return true;
-  }
-
-  return ValidateWriteParamSignature(call_expr) &&
-      ValidateWriteParamArgument(call_expr->getArg(1));
-}
-
-// Checks that IPC::WriteParam() has expected signature.
-bool CheckIPCVisitor::ValidateWriteParamSignature(
-    const CallExpr* call_expr) {
-  if (call_expr->getNumArgs() != 2) {
-    compiler_.getDiagnostics().Report(
-        call_expr->getExprLoc(), error_write_param_bad_signature_);
-    return false;
-  }
-  return true;
-}
-
-// Checks that IPC::WriteParam() argument type is allowed.
-// See CheckType() for specifics.
-bool CheckIPCVisitor::ValidateWriteParamArgument(const Expr* arg_expr) {
-  if (auto* parent_fn_decl = GetParentDecl<FunctionDecl>()) {
-    auto template_kind = parent_fn_decl->getTemplatedKind();
-    if (template_kind != FunctionDecl::TK_NonTemplate &&
-        template_kind != FunctionDecl::TK_FunctionTemplate) {
-      // Skip all specializations - we don't check WriteParam() on dependent
-      // types (typedef info gets lost), and we checked all non-dependent uses
-      // earlier (when we checked the template itself).
-      return true;
-    }
-  }
-
-  QualType arg_type;
-
-  arg_expr = arg_expr->IgnoreImplicit();
-  if (auto* cast_expr = dyn_cast<ExplicitCastExpr>(arg_expr)) {
-    arg_type = cast_expr->getTypeAsWritten();
-  } else {
-    arg_type = arg_expr->getType();
-  }
-
-  CheckDetails details;
-  if (CheckType(arg_type, &details)) {
-    return true;
-  }
-
-  ReportCheckError(details,
-                   arg_expr->getExprLoc(),
-                   error_write_param_bad_type_);
-
-  return false;
-}
-
-// Checks that IPC::CheckedTuple<> is specialized with allowed types.
-// See CheckType() above for specifics.
-bool CheckIPCVisitor::ValidateCheckedTuple(
-    const TemplateSpecializationType* spec) {
-  TemplateDecl* decl = spec->getTemplateName().getAsTemplateDecl();
-  if (!decl || decl->getQualifiedNameAsString() != "IPC::CheckedTuple") {
-    return true;
-  }
-
-  bool valid = true;
-  for (unsigned i = 0; i != spec->getNumArgs(); ++i) {
-    const TemplateArgument& arg = spec->getArg(i);
-    CheckDetails details;
-    if (CheckTemplateArgument(arg, &details)) {
-      continue;
-    }
-
-    valid = false;
-
-    auto* parent_decl = GetParentDecl<Decl>();
-    ReportCheckError(
-        details,
-        parent_decl ? parent_decl->getLocStart() : SourceLocation(),
-        error_tuple_bad_type_);
-  }
-
-  return valid;
-}
-
-template <typename T>
-const T* CheckIPCVisitor::GetParentDecl() const {
-  for (auto i = decl_stack_.rbegin(); i != decl_stack_.rend(); ++i) {
-    if (auto* parent = dyn_cast_or_null<T>(*i)) {
-      return parent;
-    }
-  }
-  return nullptr;
-}
-
-
-bool CheckIPCVisitor::IsBlacklistedType(QualType type) const {
-  return context_->hasSameUnqualifiedType(type, context_->LongTy) ||
-      context_->hasSameUnqualifiedType(type, context_->UnsignedLongTy);
-}
-
-bool CheckIPCVisitor::IsBlacklistedTypedef(const TypedefNameDecl* tdef) const {
-  return blacklisted_typedefs_.find(tdef->getName()) !=
-      blacklisted_typedefs_.end();
-}
-
-// Checks that integer type is allowed (not blacklisted).
-bool CheckIPCVisitor::CheckIntegerType(QualType type,
-                                       CheckDetails* details) const {
-  bool seen_typedef = false;
-  while (true) {
-    details->exit_type = type;
-
-    if (auto* tdef = dyn_cast<TypedefType>(type)) {
-      if (IsBlacklistedTypedef(tdef->getDecl())) {
-        return false;
-      }
-      details->typedefs.push_back(tdef);
-      seen_typedef = true;
-    }
-
-    QualType desugared_type =
-        type->getLocallyUnqualifiedSingleStepDesugaredType();
-    if (desugared_type == type) {
-      break;
-    }
-
-    type = desugared_type;
-  }
-
-  return seen_typedef || !IsBlacklistedType(type);
-}
-
-// Checks that |type| is allowed (not blacklisted), recursively visiting
-// template specializations.
-bool CheckIPCVisitor::CheckType(QualType type, CheckDetails* details) const {
-  if (type->isReferenceType()) {
-    type = type->getPointeeType();
-  }
-  type = type.getLocalUnqualifiedType();
-
-  if (details->entry_type.isNull()) {
-    details->entry_type = type;
-  }
-
-  if (type->isIntegerType()) {
-    return CheckIntegerType(type, details);
-  }
-
-  while (true) {
-    if (auto* spec = dyn_cast<TemplateSpecializationType>(type)) {
-      for (const TemplateArgument& arg: *spec) {
-        if (!CheckTemplateArgument(arg, details)) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    if (auto* record = dyn_cast<RecordType>(type)) {
-      if (auto* spec = dyn_cast<ClassTemplateSpecializationDecl>(
-              record->getDecl())) {
-        const TemplateArgumentList& args = spec->getTemplateArgs();
-        for (unsigned i = 0; i != args.size(); ++i) {
-          if (!CheckTemplateArgument(args[i], details)) {
-            return false;
-          }
-        }
-      }
-      return true;
-    }
-
-    if (auto* tdef = dyn_cast<TypedefType>(type)) {
-      details->typedefs.push_back(tdef);
-    }
-
-    QualType desugared_type =
-        type->getLocallyUnqualifiedSingleStepDesugaredType();
-    if (desugared_type == type) {
-      break;
-    }
-
-    type = desugared_type;
-  }
-
-  return true;
-}
-
-bool CheckIPCVisitor::CheckTemplateArgument(const TemplateArgument& arg,
-                                            CheckDetails* details) const {
-  return arg.getKind() != TemplateArgument::Type ||
-      CheckType(arg.getAsType(), details);
-}
-
-void CheckIPCVisitor::ReportCheckError(const CheckDetails& details,
-                                       SourceLocation loc,
-                                       unsigned error) {
-  DiagnosticsEngine& diagnostics = compiler_.getDiagnostics();
-
-  std::string entry_type = details.entry_type.getAsString();
-  std::string exit_type = details.exit_type.getAsString();
-
-  std::string via;
-  if (entry_type != exit_type) {
-    via = " via '" + entry_type + "'";
-  }
-  diagnostics.Report(loc, error) << exit_type << via;
-
-  for (const TypedefType* tdef: details.typedefs) {
-    diagnostics.Report(tdef->getDecl()->getLocation(), note_see_here_);
-  }
-}
-
-}  // namespace chrome_checker
diff --git a/tools/clang/plugins/CheckIPCVisitor.h b/tools/clang/plugins/CheckIPCVisitor.h
deleted file mode 100644
index 1ba488e..0000000
--- a/tools/clang/plugins/CheckIPCVisitor.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This check ensures that 32/64-bit unstable types are not used in IPC.
-//
-// A type (or typedef) is unstable if it changes size between 32/ 64-bit
-// platforms. However, it's impossible to accurately identify unstable
-// typedefs, because their definitions rely on the preprocessor. For
-// example uintptr_t is either unsigned int or unsigned long.
-//
-// So we're not trying to be accurate, and just blacklisting some types
-// that are known to be unstable:
-// 1. Types: long / unsigned long (but not typedefs to)
-// 2. Typedefs: intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t,
-//    size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t,
-//    time_t, suseconds_t (including typedefs to)
-//
-// Additionally, templates referencing blacklisted types (e.g. vector<long>)
-// are also blacklisted.
-//
-// Blacklisted types are checked in:
-// 1. IPC::WriteParam() calls
-// 2. IPC::CheckedTuple<> specializations
-//
-
-#ifndef TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_
-#define TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_
-
-#include <vector>
-
-#include "clang/AST/AST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "llvm/ADT/StringSet.h"
-
-namespace chrome_checker {
-
-class CheckIPCVisitor {
- public:
-  explicit CheckIPCVisitor(clang::CompilerInstance& compiler);
-
-  void set_context(clang::ASTContext* context) { context_ = context; }
-
-  bool should_visit_template_instantiations() const { return true; }
-
-  void BeginDecl(clang::Decl* decl);
-  void EndDecl();
-  void VisitTemplateSpecializationType(
-      clang::TemplateSpecializationType* spec);
-  void VisitCallExpr(clang::CallExpr* call_expr);
-
- private:
-  // ValidateXXX functions return false if validation failed and diagnostic
-  // was reported. They return true otherwise (not applicable / validation
-  // succeeded).
-
-  bool ValidateWriteParam(const clang::CallExpr* call_expr);
-  bool ValidateWriteParamSignature(const clang::CallExpr* call_expr);
-  bool ValidateWriteParamArgument(const clang::Expr* arg_expr);
-  bool ValidateCheckedTuple(
-      const clang::TemplateSpecializationType* spec);
-
-  template <typename T>
-  const T* GetParentDecl() const;
-
-  bool IsBlacklistedType(clang::QualType type) const;
-  bool IsBlacklistedTypedef(const clang::TypedefNameDecl* tdef) const;
-
-  struct CheckDetails {
-    clang::QualType entry_type;
-    clang::QualType exit_type;
-    llvm::SmallVector<const clang::TypedefType*, 5> typedefs;
-  };
-
-  bool CheckType(clang::QualType type, CheckDetails* details) const;
-  bool CheckIntegerType(clang::QualType type, CheckDetails* details) const;
-  bool CheckTemplateArgument(const clang::TemplateArgument& arg,
-                             CheckDetails* details) const;
-
-  void ReportCheckError(const CheckDetails& details,
-                        clang::SourceLocation loc,
-                        unsigned error);
-
-  clang::CompilerInstance& compiler_;
-  clang::ASTContext* context_;
-
-  unsigned error_write_param_bad_type_;
-  unsigned error_tuple_bad_type_;
-  unsigned error_write_param_bad_signature_;
-  unsigned note_see_here_;
-
-  std::vector<const clang::Decl*> decl_stack_;
-
-  llvm::StringSet<> blacklisted_typedefs_;
-};
-
-}  // namespace chrome_checker
-
-#endif  // TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_
diff --git a/tools/clang/plugins/FindBadConstructsAction.cpp b/tools/clang/plugins/FindBadConstructsAction.cpp
index f857ac2b..ad9fc55 100644
--- a/tools/clang/plugins/FindBadConstructsAction.cpp
+++ b/tools/clang/plugins/FindBadConstructsAction.cpp
@@ -21,7 +21,7 @@
       : visitor_(*instance, options) {}
 
   void HandleTranslationUnit(clang::ASTContext& context) override {
-    visitor_.Traverse(context);
+    visitor_.TraverseDecl(context.getTranslationUnitDecl());
   }
 
  private:
@@ -63,8 +63,6 @@
       options_.check_implicit_copy_ctors = true;
     } else if (args[i] == "no-realpath") {
       options_.no_realpath = true;
-    } else if (args[i] == "check-ipc") {
-      options_.check_ipc = true;
     } else {
       parsed = false;
       llvm::errs() << "Unknown clang plugin argument: " << args[i] << "\n";
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.cpp b/tools/clang/plugins/FindBadConstructsConsumer.cpp
index 46c7b8f..d1fc29d 100644
--- a/tools/clang/plugins/FindBadConstructsConsumer.cpp
+++ b/tools/clang/plugins/FindBadConstructsConsumer.cpp
@@ -103,10 +103,6 @@
 FindBadConstructsConsumer::FindBadConstructsConsumer(CompilerInstance& instance,
                                                      const Options& options)
     : ChromeClassTester(instance, options) {
-  if (options.check_ipc) {
-    ipc_visitor_.reset(new CheckIPCVisitor(instance));
-  }
-
   // Messages for virtual method specifiers.
   diag_method_requires_override_ =
       diagnostic().getCustomDiagID(getErrorLevel(), kMethodRequiresOverride);
@@ -140,24 +136,6 @@
       DiagnosticsEngine::Note, kNoteProtectedNonVirtualDtor);
 }
 
-void FindBadConstructsConsumer::Traverse(ASTContext& context) {
-  if (ipc_visitor_) ipc_visitor_->set_context(&context);
-  RecursiveASTVisitor::TraverseDecl(context.getTranslationUnitDecl());
-  if (ipc_visitor_) ipc_visitor_->set_context(nullptr);
-}
-
-bool FindBadConstructsConsumer::shouldVisitTemplateInstantiations() const {
-  return RecursiveASTVisitor::shouldVisitTemplateInstantiations() ||
-      (ipc_visitor_ && ipc_visitor_->should_visit_template_instantiations());
-}
-
-bool FindBadConstructsConsumer::TraverseDecl(Decl* decl) {
-  if (ipc_visitor_) ipc_visitor_->BeginDecl(decl);
-  bool result = RecursiveASTVisitor::TraverseDecl(decl);
-  if (ipc_visitor_) ipc_visitor_->EndDecl();
-  return result;
-}
-
 bool FindBadConstructsConsumer::VisitDecl(clang::Decl* decl) {
   clang::TagDecl* tag_decl = dyn_cast<clang::TagDecl>(decl);
   if (tag_decl && tag_decl->isCompleteDefinition())
@@ -165,17 +143,6 @@
   return true;
 }
 
-bool FindBadConstructsConsumer::VisitTemplateSpecializationType(
-    TemplateSpecializationType* spec) {
-  if (ipc_visitor_) ipc_visitor_->VisitTemplateSpecializationType(spec);
-  return true;
-}
-
-bool FindBadConstructsConsumer::VisitCallExpr(CallExpr* call_expr) {
-  if (ipc_visitor_) ipc_visitor_->VisitCallExpr(call_expr);
-  return true;
-}
-
 void FindBadConstructsConsumer::CheckChromeClass(SourceLocation record_location,
                                                  CXXRecordDecl* record) {
   // By default, the clang checker doesn't check some types (templates, etc).
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.h b/tools/clang/plugins/FindBadConstructsConsumer.h
index fb8d1d6..8f8fc87 100644
--- a/tools/clang/plugins/FindBadConstructsConsumer.h
+++ b/tools/clang/plugins/FindBadConstructsConsumer.h
@@ -20,8 +20,6 @@
 #ifndef TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_
 #define TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_
 
-#include <memory>
-
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/Attr.h"
@@ -31,7 +29,6 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceLocation.h"
 
-#include "CheckIPCVisitor.h"
 #include "ChromeClassTester.h"
 #include "Options.h"
 #include "SuppressibleDiagnosticBuilder.h"
@@ -46,14 +43,8 @@
   FindBadConstructsConsumer(clang::CompilerInstance& instance,
                             const Options& options);
 
-  void Traverse(clang::ASTContext& context);
-
   // RecursiveASTVisitor:
-  bool shouldVisitTemplateInstantiations() const;
-  bool TraverseDecl(clang::Decl* decl);
   bool VisitDecl(clang::Decl* decl);
-  bool VisitTemplateSpecializationType(clang::TemplateSpecializationType* spec);
-  bool VisitCallExpr(clang::CallExpr* call_expr);
 
   // ChromeClassTester overrides:
   void CheckChromeClass(clang::SourceLocation record_location,
@@ -119,8 +110,6 @@
   unsigned diag_note_implicit_dtor_;
   unsigned diag_note_public_dtor_;
   unsigned diag_note_protected_non_virtual_dtor_;
-
-  std::unique_ptr<CheckIPCVisitor> ipc_visitor_;
 };
 
 }  // namespace chrome_checker
diff --git a/tools/clang/plugins/Options.h b/tools/clang/plugins/Options.h
index 684dab52b..e56084e 100644
--- a/tools/clang/plugins/Options.h
+++ b/tools/clang/plugins/Options.h
@@ -17,10 +17,10 @@
   // This is needed during the migration from ASTConsumer approach to the
   // RecursiveASTVisitor approach. See https://crbug.com/436357 for details.
   bool check_implicit_copy_ctors = false;
+
   // This is needed for some distributed build-sytems to respect banned
   // paths. See https://crbug.com/583454 for details.
   bool no_realpath = false;
-  bool check_ipc = false;
 };
 
 }  // namespace chrome_checker
diff --git a/tools/clang/plugins/tests/ipc.cpp b/tools/clang/plugins/tests/ipc.cpp
deleted file mode 100644
index d2bcef1..0000000
--- a/tools/clang/plugins/tests/ipc.cpp
+++ /dev/null
@@ -1,353 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Blacklisted typedefs
-typedef __INTMAX_TYPE__ intmax_t;
-typedef __UINTMAX_TYPE__ uintmax_t;
-typedef int intptr_t;
-typedef unsigned int uintptr_t;
-typedef __WINT_TYPE__ wint_t;
-typedef __SIZE_TYPE__ size_t;
-typedef __SIZE_TYPE__ rsize_t;
-typedef long ssize_t;
-typedef __PTRDIFF_TYPE__ ptrdiff_t;
-typedef unsigned int dev_t;
-typedef int off_t;
-typedef long clock_t;
-typedef int time_t;
-typedef long suseconds_t;
-
-// Other typedefs
-typedef int int32_t;
-typedef unsigned int uint32_t;
-typedef long int64_t;
-typedef unsigned long uint64_t;
-
-namespace std {
-
-template <class T>
-struct allocator {};
-
-template <class T, class A = allocator<T>>
-struct vector {};
-
-template <class F, class S>
-struct pair {};
-
-}  // namespace std
-
-namespace base {
-
-class Pickle {};
-
-template <class T, class... Ts>
-struct Tuple {
-  T value;
-};
-
-}  // namespace base
-
-namespace IPC {
-
-template <class... T>
-struct CheckedTuple {
-  typedef base::Tuple<T...> Tuple;
-};
-
-template <class T>
-struct ParamTraits {
-  static void Write(base::Pickle*, const T&) {}
-};
-
-template <class T>
-void WriteParam(base::Pickle* pickle, const T& value) {
-  ParamTraits<T>::Write(pickle, value);
-}
-
-}  // namespace IPC
-
-
-/* Test IPC::WriteParam() usage in templates. ERRORS: 6 */
-
-struct Data {
-  uint32_t value;
-  size_t size;
-};
-
-template <>
-struct IPC::ParamTraits<Data> {
-  static void Write(base::Pickle* pickle, const Data& p) {
-    // OK: WriteParam() called in explicit specialization
-    WriteParam(pickle, p.value); // OK
-    WriteParam(pickle, p.size); // ERROR
-  }
-};
-
-template <class T>
-struct Container {
-  T value;
-};
-
-template <class T>
-struct IPC::ParamTraits<Container<T>> {
-  static void Write(base::Pickle* pickle, const Container<T>& container) {
-    // NOT CHECKED: T is not explicitly referenced
-    IPC::WriteParam(pickle, container.value); // NOT CHECKED
-    WriteParam(pickle, container.value); // NOT CHECKED
-
-    // NOT CHECKED: T explicitly referenced
-    IPC::WriteParam<T>(pickle, container.value); // NOT CHECKED
-    WriteParam<T>(pickle, container.value); // NOT CHECKED
-
-    // OK: explicit cast to non-dependent allowed type
-    WriteParam(pickle, static_cast<uint32_t>(container.value)); // OK
-
-    // ERROR: explicit cast to non-dependent banned type
-    WriteParam(pickle, static_cast<long>(container.value)); // ERROR
-  }
-};
-
-template <class T, class... Ts>
-struct MultiContainer {
-  T value;
-};
-
-template <class T, class... Ts>
-struct IPC::ParamTraits<MultiContainer<T, Ts...>> {
-  static void Write(base::Pickle* pickle,
-                    const MultiContainer<T, Ts...>& container) {
-    // NOT CHECKED: template argument explicitly referenced
-    bool helper[] = {
-        (WriteParam<Ts>(pickle, container.value), true)... // NOT CHECKED
-    };
-    (void)helper;
-  }
-};
-
-template <class T>
-struct SomeClass {
-  static void Write(base::Pickle* pickle) {
-    // NOT CHECKED: WriteParam() calls on dependent types
-    IPC::WriteParam(pickle, T(0)); // NOT CHECKED
-
-    // Non-dependent types are checked
-    IPC::WriteParam(pickle, size_t(0)); // ERROR
-    IPC::WriteParam(pickle, uint64_t(0)); // OK
-  }
-
-  template <class U>
-  static void WriteEx(base::Pickle* pickle) {
-    // NOT CHECKED: WriteParam() calls on dependent types
-    IPC::WriteParam(pickle, U(0)); // NOT CHECKED
-
-    // Non-dependent types are checked
-    IPC::WriteParam(pickle, time_t(0)); // ERROR
-    IPC::WriteParam(pickle, uint32_t(0)); // OK
-  }
-};
-
-template <class T>
-void SomeWriteFunction(base::Pickle* pickle) {
-  // NOT CHECKED: WriteParam() calls on dependent types
-  IPC::WriteParam(pickle, T(0)); // NOT CHECKED
-
-  // Non-dependent types are checked
-  IPC::WriteParam(pickle, long(0)); // ERROR
-  IPC::WriteParam(pickle, char(0)); // OK
-
-  [&](){
-    IPC::WriteParam(pickle, T(0)); // NOT CHECKED
-
-    IPC::WriteParam(pickle, clock_t(0)); // ERROR
-    IPC::WriteParam(pickle, int64_t(0)); // OK
-  }();
-}
-
-void TestWriteParamInTemplates() {
-  // These specializations call WriteParam() on various banned types, either
-  // because they were specified directly (long) or because non-blacklisted
-  // typedef (uint64_t) was stripped down to its underlying type, which is
-  // blacklisted when used as is (unsigned long).
-  // However, since it's hard (if not impossible) to check specializations
-  // properly, we're simply not checking them.
-  SomeClass<long>::Write(nullptr);
-  SomeClass<long>::WriteEx<uint64_t>(nullptr);
-  SomeWriteFunction<uint64_t>(nullptr);
-}
-
-
-/* Test IPC::CheckedTuple. ERRORS: 5 */
-
-#define IPC_TUPLE(...) IPC::CheckedTuple<__VA_ARGS__>::Tuple
-
-#define IPC_MESSAGE_DECL(name, id, in_tuple) \
-  struct name ## Meta_ ## id { \
-    using InTuple = in_tuple; \
-  };
-
-#define IPC_TEST_MESSAGE(id, in) \
-  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
-
-struct Empty {};
-
-IPC_TEST_MESSAGE(__COUNTER__, (bool, size_t, Empty, long)) // 2 ERRORs
-
-typedef std::vector<long> long1D;
-typedef std::vector<long1D> long2D;
-IPC_TEST_MESSAGE(__COUNTER__, (bool, long2D)) // ERROR
-
-IPC_TEST_MESSAGE(__COUNTER__, (char, short, std::pair<size_t, bool>)) // ERROR
-
-IPC_TEST_MESSAGE(__COUNTER__, (std::vector<std::vector<long&>&>&)) // ERROR
-
-
-/* Check IPC::WriteParam() arguments. ERRORS: 30 */
-
-// ERRORS: 21
-void TestWriteParamArgument() {
-  #define CALL_WRITEPARAM(Type) \
-    { \
-      Type p; \
-      IPC::WriteParam(nullptr, p); \
-    }
-
-  // ERROR: blacklisted types / typedefs
-  CALL_WRITEPARAM(long) // ERROR
-  CALL_WRITEPARAM(unsigned long) // ERROR
-  CALL_WRITEPARAM(intmax_t) // ERROR
-  CALL_WRITEPARAM(uintmax_t) // ERROR
-  CALL_WRITEPARAM(intptr_t) // ERROR
-  CALL_WRITEPARAM(uintptr_t) // ERROR
-  CALL_WRITEPARAM(wint_t) // ERROR
-  CALL_WRITEPARAM(size_t) // ERROR
-  CALL_WRITEPARAM(rsize_t) // ERROR
-  CALL_WRITEPARAM(ssize_t) // ERROR
-  CALL_WRITEPARAM(ptrdiff_t) // ERROR
-  CALL_WRITEPARAM(dev_t) // ERROR
-  CALL_WRITEPARAM(off_t) // ERROR
-  CALL_WRITEPARAM(clock_t) // ERROR
-  CALL_WRITEPARAM(time_t) // ERROR
-  CALL_WRITEPARAM(suseconds_t) // ERROR
-
-  // ERROR: typedef to blacklisted typedef
-  typedef size_t my_size;
-  CALL_WRITEPARAM(my_size) // ERROR
-
-  // ERROR: expression ends up with type "unsigned long"
-  {
-    uint64_t p = 0;
-    IPC::WriteParam(nullptr, p + 1); // ERROR
-  }
-
-  // ERROR: long chain of typedefs, ends up with blacklisted typedef
-  {
-    typedef size_t my_size_base;
-    typedef const my_size_base my_size;
-    typedef my_size& my_size_ref;
-    my_size_ref p = 0;
-    IPC::WriteParam(nullptr, p); // ERROR
-  }
-
-  // ERROR: template specialization references blacklisted type
-  CALL_WRITEPARAM(std::vector<long>) // ERROR
-  CALL_WRITEPARAM(std::vector<size_t>) // ERROR
-
-  // OK: typedef to blacklisted type
-  typedef long my_long;
-  CALL_WRITEPARAM(my_long) // OK
-
-  // OK: other types / typedefs
-  CALL_WRITEPARAM(char) // OK
-  CALL_WRITEPARAM(int) // OK
-  CALL_WRITEPARAM(uint32_t) // OK
-  CALL_WRITEPARAM(int64_t) // OK
-
-  // OK: long chain of typedefs, ends up with non-blacklisted typedef
-  {
-    typedef uint32_t my_int_base;
-    typedef const my_int_base my_int;
-    typedef my_int& my_int_ref;
-    my_int_ref p = 0;
-    IPC::WriteParam(nullptr, p); // OK
-  }
-
-  // OK: template specialization references non-blacklisted type
-  CALL_WRITEPARAM(std::vector<char>) // OK
-  CALL_WRITEPARAM(std::vector<my_long>) // OK
-
-  #undef CALL_WRITEPARAM
-}
-
-struct Provider {
-  typedef unsigned int flags;
-
-  short get_short() const { return 0; }
-  uint64_t get_uint64() const { return 0; }
-  long get_long() const { return 0; }
-  unsigned int get_uint() const { return 0; }
-  flags get_flags() const { return 0; }
-  size_t get_size() const { return 0; }
-
-  const std::vector<size_t>& get_sizes() const { return sizes_data; }
-  const std::vector<uint64_t>& get_uint64s() const { return uint64s_data; }
-
-  template <class T>
-  T get() const { return T(); }
-
-  short short_data;
-  unsigned int uint_data;
-  flags flags_data;
-  long long_data;
-  size_t size_data;
-  uint64_t uint64_data;
-  std::vector<size_t> sizes_data;
-  std::vector<uint64_t> uint64s_data;
-};
-
-// ERRORS: 9
-void TestWriteParamMemberArgument() {
-  Provider p;
-
-  IPC::WriteParam(nullptr, p.get<short>()); // OK
-  IPC::WriteParam(nullptr, p.get_short()); // OK
-  IPC::WriteParam(nullptr, p.short_data); // OK
-
-  IPC::WriteParam(nullptr, p.get<unsigned int>()); // OK
-  IPC::WriteParam(nullptr, p.get_uint()); // OK
-  IPC::WriteParam(nullptr, p.uint_data); // OK
-
-  IPC::WriteParam(nullptr, p.get<Provider::flags>()); // OK
-  IPC::WriteParam(nullptr, p.get_flags()); // OK
-  IPC::WriteParam(nullptr, p.flags_data); // OK
-
-  IPC::WriteParam(nullptr, p.get<long>()); // ERROR
-  IPC::WriteParam(nullptr, p.get_long()); // ERROR
-  IPC::WriteParam(nullptr, p.long_data); // ERROR
-
-  // This one is flaky and depends on whether size_t is typedefed to a
-  // blacklisted type (unsigned long).
-  //IPC::WriteParam(nullptr, p.get<size_t>()); // ERROR
-  IPC::WriteParam(nullptr, p.get_size()); // ERROR
-  IPC::WriteParam(nullptr, p.size_data); // ERROR
-
-  // Information about uint64_t gets lost, and plugin sees WriteParam()
-  // call on unsigned long, which is blacklisted.
-  IPC::WriteParam(nullptr, p.get<uint64_t>()); // ERROR
-  IPC::WriteParam(nullptr, p.get_uint64()); // OK
-  IPC::WriteParam(nullptr, p.uint64_data); // OK
-
-  // Same thing here, WriteParam() sees vector<unsigned long>, and denies it.
-  IPC::WriteParam(nullptr, p.get<std::vector<uint64_t>>()); // ERROR
-  IPC::WriteParam(nullptr, p.get_uint64s()); // OK
-  IPC::WriteParam(nullptr, p.uint64s_data); // OK
-
-  // This one is flaky and depends on whether size_t is typedefed to a
-  // blacklisted type (unsigned long).
-  //IPC::WriteParam(nullptr, p.get<std::vector<size_t>>());
-  IPC::WriteParam(nullptr, p.get_sizes()); // ERROR
-  IPC::WriteParam(nullptr, p.sizes_data); // ERROR
-}
-
-
-/* ERRORS: 41 */
diff --git a/tools/clang/plugins/tests/ipc.flags b/tools/clang/plugins/tests/ipc.flags
deleted file mode 100644
index 33926b6..0000000
--- a/tools/clang/plugins/tests/ipc.flags
+++ /dev/null
@@ -1 +0,0 @@
--ferror-limit=0 -Xclang -plugin-arg-find-bad-constructs -Xclang check-ipc -fno-delayed-template-parsing
\ No newline at end of file
diff --git a/tools/clang/plugins/tests/ipc.txt b/tools/clang/plugins/tests/ipc.txt
deleted file mode 100644
index fbca40b..0000000
--- a/tools/clang/plugins/tests/ipc.txt
+++ /dev/null
@@ -1,224 +0,0 @@
-ipc.cpp:83:26: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t'.
-    WriteParam(pickle, p.size); // ERROR
-                         ^
-ipc.cpp:107:24: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
-    WriteParam(pickle, static_cast<long>(container.value)); // ERROR
-                       ^
-ipc.cpp:135:29: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t'.
-    IPC::WriteParam(pickle, size_t(0)); // ERROR
-                            ^
-ipc.cpp:145:29: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'time_t'.
-    IPC::WriteParam(pickle, time_t(0)); // ERROR
-                            ^
-ipc.cpp:156:27: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
-  IPC::WriteParam(pickle, long(0)); // ERROR
-                          ^
-ipc.cpp:162:29: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'clock_t'.
-    IPC::WriteParam(pickle, clock_t(0)); // ERROR
-                            ^
-ipc.cpp:194:1: error: [chromium-ipc] IPC tuple references banned type 'size_t'.
-IPC_TEST_MESSAGE(__COUNTER__, (bool, size_t, Empty, long)) // 2 ERRORs
-^
-ipc.cpp:190:3: note: expanded from macro 'IPC_TEST_MESSAGE'
-  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
-  ^
-ipc.cpp:186:5: note: expanded from macro 'IPC_MESSAGE_DECL'
-    using InTuple = in_tuple; \
-    ^
-ipc.cpp:194:1: error: [chromium-ipc] IPC tuple references banned type 'long'.
-ipc.cpp:190:3: note: expanded from macro 'IPC_TEST_MESSAGE'
-  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
-  ^
-ipc.cpp:186:5: note: expanded from macro 'IPC_MESSAGE_DECL'
-    using InTuple = in_tuple; \
-    ^
-ipc.cpp:198:1: error: [chromium-ipc] IPC tuple references banned type 'long' via 'long2D'.
-IPC_TEST_MESSAGE(__COUNTER__, (bool, long2D)) // ERROR
-^
-ipc.cpp:190:3: note: expanded from macro 'IPC_TEST_MESSAGE'
-  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
-  ^
-ipc.cpp:186:5: note: expanded from macro 'IPC_MESSAGE_DECL'
-    using InTuple = in_tuple; \
-    ^
-ipc.cpp:197:29: note: see here
-typedef std::vector<long1D> long2D;
-                            ^
-ipc.cpp:196:27: note: see here
-typedef std::vector<long> long1D;
-                          ^
-ipc.cpp:200:1: error: [chromium-ipc] IPC tuple references banned type 'size_t' via 'std::pair<size_t, _Bool>'.
-IPC_TEST_MESSAGE(__COUNTER__, (char, short, std::pair<size_t, bool>)) // ERROR
-^
-ipc.cpp:190:3: note: expanded from macro 'IPC_TEST_MESSAGE'
-  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
-  ^
-ipc.cpp:186:5: note: expanded from macro 'IPC_MESSAGE_DECL'
-    using InTuple = in_tuple; \
-    ^
-ipc.cpp:202:1: error: [chromium-ipc] IPC tuple references banned type 'long' via 'std::vector<std::vector<long &> &>'.
-IPC_TEST_MESSAGE(__COUNTER__, (std::vector<std::vector<long&>&>&)) // ERROR
-^
-ipc.cpp:190:3: note: expanded from macro 'IPC_TEST_MESSAGE'
-  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
-  ^
-ipc.cpp:186:5: note: expanded from macro 'IPC_MESSAGE_DECL'
-    using InTuple = in_tuple; \
-    ^
-ipc.cpp:216:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
-  CALL_WRITEPARAM(long) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:217:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'unsigned long'.
-  CALL_WRITEPARAM(unsigned long) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:218:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'intmax_t'.
-  CALL_WRITEPARAM(intmax_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:219:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'uintmax_t'.
-  CALL_WRITEPARAM(uintmax_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:220:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'intptr_t'.
-  CALL_WRITEPARAM(intptr_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:221:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'uintptr_t'.
-  CALL_WRITEPARAM(uintptr_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:222:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'wint_t'.
-  CALL_WRITEPARAM(wint_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:223:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t'.
-  CALL_WRITEPARAM(size_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:224:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'rsize_t'.
-  CALL_WRITEPARAM(rsize_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:225:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'ssize_t'.
-  CALL_WRITEPARAM(ssize_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:226:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'ptrdiff_t'.
-  CALL_WRITEPARAM(ptrdiff_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:227:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'dev_t'.
-  CALL_WRITEPARAM(dev_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:228:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'off_t'.
-  CALL_WRITEPARAM(off_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:229:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'clock_t'.
-  CALL_WRITEPARAM(clock_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:230:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'time_t'.
-  CALL_WRITEPARAM(time_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:231:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'suseconds_t'.
-  CALL_WRITEPARAM(suseconds_t) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:235:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t' via 'my_size'.
-  CALL_WRITEPARAM(my_size) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:234:18: note: see here
-  typedef size_t my_size;
-                 ^
-ipc.cpp:240:32: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'unsigned long'.
-    IPC::WriteParam(nullptr, p + 1); // ERROR
-                               ^
-ipc.cpp:249:30: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t' via 'my_size'.
-    IPC::WriteParam(nullptr, p); // ERROR
-                             ^
-ipc.cpp:246:32: note: see here
-    typedef const my_size_base my_size;
-                               ^
-ipc.cpp:245:20: note: see here
-    typedef size_t my_size_base;
-                   ^
-ipc.cpp:253:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long' via 'std::vector<long>'.
-  CALL_WRITEPARAM(std::vector<long>) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:254:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t' via 'std::vector<size_t>'.
-  CALL_WRITEPARAM(std::vector<size_t>) // ERROR
-  ^
-ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
-      IPC::WriteParam(nullptr, p); \
-                               ^
-ipc.cpp:324:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
-  IPC::WriteParam(nullptr, p.get<long>()); // ERROR
-                           ^
-ipc.cpp:325:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
-  IPC::WriteParam(nullptr, p.get_long()); // ERROR
-                           ^
-ipc.cpp:326:30: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
-  IPC::WriteParam(nullptr, p.long_data); // ERROR
-                             ^
-ipc.cpp:331:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t'.
-  IPC::WriteParam(nullptr, p.get_size()); // ERROR
-                           ^
-ipc.cpp:332:30: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t'.
-  IPC::WriteParam(nullptr, p.size_data); // ERROR
-                             ^
-ipc.cpp:336:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'unsigned long'.
-  IPC::WriteParam(nullptr, p.get<uint64_t>()); // ERROR
-                           ^
-ipc.cpp:341:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'unsigned long' via 'struct std::vector<unsigned long, struct std::allocator<unsigned long> >'.
-  IPC::WriteParam(nullptr, p.get<std::vector<uint64_t>>()); // ERROR
-                           ^
-ipc.cpp:348:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t' via 'std::vector<size_t>'.
-  IPC::WriteParam(nullptr, p.get_sizes()); // ERROR
-                           ^
-ipc.cpp:349:30: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t' via 'std::vector<size_t>'.
-  IPC::WriteParam(nullptr, p.sizes_data); // ERROR
-                             ^
-41 errors generated.
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index b1a59b7..e3fa1b1 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -26,7 +26,7 @@
 # Do NOT CHANGE this if you don't know what you're doing -- see
 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
 # Reverting problematic clang rolls is safe, though.
-CLANG_REVISION = '261368'
+CLANG_REVISION = '262839'
 
 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ
 if use_head_revision:
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 3819685..7e192cd 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -12351,6 +12351,15 @@
   </summary>
 </histogram>
 
+<histogram name="Extensions.AppLoadedInTab" enum="AppLoadedInTabSource">
+  <owner>lazyboy@chromium.org</owner>
+  <summary>
+    A platform app ended up in a regular tab either by the app page or its
+    background page. Note that this happens unexpectedly right now and we wish
+    to track its usage before removing the supporting code.
+  </summary>
+</histogram>
+
 <histogram name="Extensions.AppLocation" enum="ExtensionLocation">
   <owner>benwells@chromium.org</owner>
   <owner>tapted@chromium.org</owner>
@@ -20892,6 +20901,15 @@
   </summary>
 </histogram>
 
+<histogram name="MediaRouter.Route.CreationOutcome"
+    units="MediaRouterCreateRouteOutcome">
+  <owner>apacible@chromium.org</owner>
+  <summary>
+    The number of times a Media Router create route response succeeds or fails.
+    This breaks down the different failure types in to separate buckets.
+  </summary>
+</histogram>
+
 <histogram name="MediaRouter.Ui.Action.CloseLatency" units="ms">
   <owner>apacible@chromium.org</owner>
   <summary>
@@ -34163,6 +34181,10 @@
 
 <histogram name="PasswordManager.InfoBarResponse" enum="InfoBarResponse">
   <owner>vabr@chromium.org</owner>
+  <obsolete>
+    Deprecated as of 03/2016. This metric has been replaced by
+    PasswordManager.UIDismissalReason.
+  </obsolete>
   <summary>
     The distribution of responses to the &quot;Do you want Chrome to remember
     this password&quot;? info bar prompt.
@@ -34332,6 +34354,9 @@
 <histogram name="PasswordManager.SavePasswordPromptDisappearedQuickly"
     enum="Boolean">
   <owner>vabr@chromium.org</owner>
+  <obsolete>
+    Deprecated as of 03/2016.
+  </obsolete>
   <summary>
     Indicates whether the save password prompt disappeared in less than one
     second. This most likely indicates that the prompt was dismissed
@@ -34342,12 +34367,18 @@
 
 <histogram name="PasswordManager.SavePasswordPromptDisplayed" enum="Boolean">
   <owner>vabr@chromium.org</owner>
+  <obsolete>
+    Deprecated as of 03/2016.
+  </obsolete>
   <summary>Indicates whether the save password prompt was displayed.</summary>
 </histogram>
 
 <histogram name="PasswordManager.SavePasswordPromptResponse"
     enum="SavePasswordPromptResponseType">
   <owner>vabr@chromium.org</owner>
+  <obsolete>
+    Deprecated as of 03/2016.
+  </obsolete>
   <summary>
     Breakdown of which response the user selected from the save password prompt.
   </summary>
@@ -36967,6 +36998,9 @@
 </histogram>
 
 <histogram name="PLT.PT.NavigationStartToFirstLayout" units="ms">
+  <obsolete>
+    Deprecated. Use PageLoad.Timing2.* instead.
+  </obsolete>
   <owner>bmcquade@chromium.org</owner>
   <summary>
     Measures the time from navigation timing's navigation start to the time the
@@ -36975,6 +37009,9 @@
 </histogram>
 
 <histogram name="PLT.PT.ResponseStartToFirstLayout" units="ms">
+  <obsolete>
+    Deprecated. Use PageLoad.Timing2.* instead.
+  </obsolete>
   <owner>bmcquade@chromium.org</owner>
   <summary>
     Measures the time from navigation timing's response start to the time the
@@ -59076,6 +59113,11 @@
   <int value="3" label="RECOMMENDATION"/>
 </enum>
 
+<enum name="AppLoadedInTabSource" type="int">
+  <int value="0" label="SOURCE_APP"/>
+  <int value="1" label="SOURCE_BACKGROUND_PAGE"/>
+</enum>
+
 <enum name="AppLocation" type="int">
   <int value="0" label="Invalid location"/>
   <int value="1" label="Internal extension"/>
@@ -73951,6 +73993,12 @@
   <int value="14" label="ConnectRouteByRouteId"/>
 </enum>
 
+<enum name="MediaRouterCreateRouteOutcome" type="int">
+  <int value="0" label="Success"/>
+  <int value="1" label="Failure No Route"/>
+  <int value="2" label="Failure Invalid Sink"/>
+</enum>
+
 <enum name="MediaRouterDialogOpenOrigin" type="int">
   <int value="0" label="Toolbar"/>
   <int value="1" label="Overflow Menu"/>
@@ -88016,6 +88064,9 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="PasswordManagerMonitor">
+  <obsolete>
+    Deprecated as of 03/2016.
+  </obsolete>
   <suffix name="group_1" label="group 1"/>
   <suffix name="group_2" label="group 2"/>
   <suffix name="group_3" label="group 3"/>
diff --git a/tools/perf/benchmarks/blink_style.py b/tools/perf/benchmarks/blink_style.py
index d37d44af..60b31c5bb 100644
--- a/tools/perf/benchmarks/blink_style.py
+++ b/tools/perf/benchmarks/blink_style.py
@@ -31,6 +31,11 @@
   page_set = page_sets.KeyMobileSitesPageSet
 
   @classmethod
+  def ShouldDisable(cls, possible_browser):  # http://crbug.com/593152
+    return (possible_browser.browser_type == 'reference' and
+            possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X')
+
+  @classmethod
   def Name(cls):
     return 'blink_style.key_mobile_sites'
 
diff --git a/tools/perf/benchmarks/memory.py b/tools/perf/benchmarks/memory.py
index bf214a3..dc38dbb8 100644
--- a/tools/perf/benchmarks/memory.py
+++ b/tools/perf/benchmarks/memory.py
@@ -38,17 +38,6 @@
     return cls.IsSvelte(possible_browser)  # http://crbug.com/555092
 
 
-class MemoryLongRunningIdleGmail(perf_benchmark.PerfBenchmark):
-  """Use (recorded) real world web sites and measure memory consumption
-  of long running idle Gmail page """
-  test = memory.Memory
-  page_set = page_sets.LongRunningIdleGmailPageSet
-
-  @classmethod
-  def Name(cls):
-    return 'memory.long_running_idle_gmail'
-
-
 @benchmark.Disabled('android')  # crbug.com/542682
 class MemoryLongRunningIdleGmailBackground(perf_benchmark.PerfBenchmark):
   """Use (recorded) real world web sites and measure memory consumption
diff --git a/tools/perf/benchmarks/memory_infra.py b/tools/perf/benchmarks/memory_infra.py
index 737f9287..e7934e6 100644
--- a/tools/perf/benchmarks/memory_infra.py
+++ b/tools/perf/benchmarks/memory_infra.py
@@ -10,6 +10,7 @@
 from telemetry.timeline import tracing_category_filter
 from telemetry.web_perf import timeline_based_measurement
 from telemetry.web_perf.metrics import memory_timeline
+from telemetry.web_perf.metrics import v8_gc_latency
 
 import page_sets
 
@@ -43,6 +44,7 @@
     return True
 
   def SetupBenchmarkDefaultTraceRerunOptions(self, tbm_options):
+    # TODO(perezju): Call this function for TBM benchmarks: crbug.com/593678
     tbm_options.SetLegacyTimelineBasedMetrics((
         memory_timeline.MemoryTimelineMetric(),
     ))
@@ -115,3 +117,36 @@
   @classmethod
   def Name(cls):
     return 'memory.top_10_mobile'
+
+
+# Disabled on reference builds because they don't support the new
+# Tracing.requestMemoryDump DevTools API.
+# For 'reference' see http://crbug.com/540022.
+# For 'android' see http://crbug.com/579546.
+@benchmark.Disabled('reference', 'android')
+class MemoryLongRunningIdleGmailTBM(_MemoryInfra):
+  """Use (recorded) real world web sites and measure memory consumption
+  of long running idle Gmail page """
+  page_set = page_sets.LongRunningIdleGmailPageSet
+
+  def CreateTimelineBasedMeasurementOptions(self):
+    v8_categories = [
+        'blink.console', 'renderer.scheduler', 'v8', 'webkit.console']
+    memory_categories = 'blink.console,disabled-by-default-memory-infra'
+    category_filter = tracing_category_filter.TracingCategoryFilter(
+        memory_categories)
+    for category in v8_categories:
+      category_filter.AddIncludedCategory(category)
+    options = timeline_based_measurement.Options(category_filter)
+    options.SetLegacyTimelineBasedMetrics([
+        v8_gc_latency.V8GCLatency(),
+        memory_timeline.MemoryTimelineMetric()])
+    return options
+
+  @classmethod
+  def Name(cls):
+    return 'memory.long_running_idle_gmail_tbm'
+
+  @classmethod
+  def ShouldTearDownStateAfterEachStoryRun(cls):
+    return True
diff --git a/tools/perf/benchmarks/page_cycler.py b/tools/perf/benchmarks/page_cycler.py
index 8da5f3b1..c23ae720 100644
--- a/tools/perf/benchmarks/page_cycler.py
+++ b/tools/perf/benchmarks/page_cycler.py
@@ -227,6 +227,11 @@
   options = {'pageset_repeat': 3}
 
   @classmethod
+  def ShouldDisable(cls, possible_browser):  # http://crbug.com/593152
+    return (possible_browser.browser_type == 'reference' and
+            possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X')
+
+  @classmethod
   def Name(cls):
     return 'page_cycler.typical_25'
 
diff --git a/tools/perf/benchmarks/power.py b/tools/perf/benchmarks/power.py
index 3297db2..d4ebde9 100644
--- a/tools/perf/benchmarks/power.py
+++ b/tools/perf/benchmarks/power.py
@@ -30,6 +30,11 @@
   test = power.Power
   page_set = page_sets.Typical10MobilePageSet
 
+  @classmethod
+  def ShouldDisable(cls, possible_browser):  # http://crbug.com/593152
+    return (possible_browser.browser_type == 'reference' and
+            possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X')
+
   def SetExtraBrowserOptions(self, options):
     options.full_performance_mode = False
 
diff --git a/tools/perf/benchmarks/smoothness.py b/tools/perf/benchmarks/smoothness.py
index b85e4b44..733a136 100644
--- a/tools/perf/benchmarks/smoothness.py
+++ b/tools/perf/benchmarks/smoothness.py
@@ -491,6 +491,11 @@
   page_set = page_sets.ScrollingToughAdCasesPageSet
 
   @classmethod
+  def ShouldDisable(cls, possible_browser):  # http://crbug.com/593152
+    return (possible_browser.browser_type == 'reference' and
+            possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X')
+
+  @classmethod
   def Name(cls):
     return 'smoothness.scrolling_tough_ad_cases'
 
diff --git a/tools/perf/benchmarks/v8.py b/tools/perf/benchmarks/v8.py
index aebdf64..68e11c8 100644
--- a/tools/perf/benchmarks/v8.py
+++ b/tools/perf/benchmarks/v8.py
@@ -26,6 +26,11 @@
   page_set = page_sets.V8Top25SmoothPageSet
 
   @classmethod
+  def ShouldDisable(cls, possible_browser):  # http://crbug.com/593152
+    return (possible_browser.browser_type == 'reference' and
+            possible_browser.platform.GetDeviceTypeName() == 'Nexus 5X')
+
+  @classmethod
   def Name(cls):
     return 'v8.top_25_smooth'
 
diff --git a/tools/perf/core/trybot_command.py b/tools/perf/core/trybot_command.py
index ce940270..b4073876 100644
--- a/tools/perf/core/trybot_command.py
+++ b/tools/perf/core/trybot_command.py
@@ -271,7 +271,7 @@
         'CL for perf tryjob on %s' % bot_platform
     ])
     if returncode:
-      raise TrybotError('Could upload to rietveld for %s, error %s' %
+      raise TrybotError('Could not upload to rietveld for %s, error %s' %
                         (bot_platform, err))
 
     match = re.search(r'https://codereview.chromium.org/[\d]+', out)
diff --git a/tools/perf/page_sets/long_running_idle_google_cases.py b/tools/perf/page_sets/long_running_idle_google_cases.py
index ee3f5c75..9b46f8c 100644
--- a/tools/perf/page_sets/long_running_idle_google_cases.py
+++ b/tools/perf/page_sets/long_running_idle_google_cases.py
@@ -6,12 +6,19 @@
 
 from page_sets import google_pages
 
+STARTUP_TIME_IN_SECONDS = 2
 IDLE_TIME_IN_SECONDS = 100
 
 def _CreateIdlePageClass(base_page_cls):
   class DerivedIdlePage(base_page_cls):  # pylint: disable=no-init
     def RunPageInteractions(self, action_runner):
-      action_runner.Wait(IDLE_TIME_IN_SECONDS)
+      action_runner.Wait(STARTUP_TIME_IN_SECONDS)
+      with action_runner.CreateInteraction('Begin'):
+        action_runner.tab.browser.DumpMemory()
+      with action_runner.CreateInteraction('Idle'):
+        action_runner.Wait(IDLE_TIME_IN_SECONDS)
+      with action_runner.CreateInteraction('End'):
+        action_runner.tab.browser.DumpMemory()
   return DerivedIdlePage
 
 
@@ -39,4 +46,4 @@
         archive_data_file='data/long_running_idle_gmail_page.json',
         cloud_storage_bucket=story.PARTNER_BUCKET)
     self.AddStory(
-        _CreateIdleBackgroundPageClass(google_pages.GmailPage)(self))
\ No newline at end of file
+        _CreateIdleBackgroundPageClass(google_pages.GmailPage)(self))
diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt
index 75e81a5..5d45b4e 100644
--- a/tools/valgrind/memcheck/suppressions.txt
+++ b/tools/valgrind/memcheck/suppressions.txt
@@ -307,8 +307,8 @@
    bug_86301 This test explicitly verifies PostTaskAndReply leaks the task if the originating MessageLoop has been deleted.
    Memcheck:Leak
    fun:_Znw*
-   fun:_ZN4base8internal20PostTaskAndReplyImpl16PostTaskAndReplyERKN15tracked_objects8LocationERKNS_8CallbackIFvvEEESA_
-   fun:_ZN4base10TaskRunner16PostTaskAndReplyERKN15tracked_objects8LocationERKNS_8CallbackIFvvEEES9_
+   fun:_ZN4base8internal20PostTaskAndReplyImpl16PostTaskAndReplyERKN15tracked_objects8LocationERKNS_8CallbackIFvvELNS0_8CopyMode*
+   fun:_ZN4base10TaskRunner16PostTaskAndReplyERKN15tracked_objects8LocationERKNS_8CallbackIFvvELNS_8internal8CopyMode*
    fun:_ZN4base74MessageLoopTaskRunnerTest_PostTaskAndReply_DeadReplyLoopDoesNotDelete_Test8TestBodyEv
 }
 {
@@ -557,11 +557,12 @@
    Memcheck:Leak
    fun:_Znw*
    fun:_ZN4base22PosixDynamicThreadPool7AddTaskEPNS_11PendingTaskE
-   fun:_ZN4base22PosixDynamicThreadPool8PostTaskERKN15tracked_objects8LocationERKNS_8CallbackIFvvEEE
-   fun:_ZN4base12_GLOBAL__N_114WorkerPoolImpl8PostTaskERKN15tracked_objects8LocationERKNS_8CallbackIFvvEEEb
-   fun:_ZN4base10WorkerPool8PostTaskERKN15tracked_objects8LocationERKNS_8CallbackIFvvEEEb
+   fun:_ZN4base22PosixDynamicThreadPool8PostTaskERKN15tracked_objects8LocationERKNS_8CallbackIF*
+   fun:_ZN4base12_GLOBAL__N_114WorkerPoolImpl8PostTaskERKN15tracked_objects8LocationERKNS_8CallbackIF*
+   fun:_ZN4base10WorkerPool8PostTaskERKN15tracked_objects8LocationERKNS_8CallbackIF*
 }
 
+
 #-----------------------------------------------------------------------
 # 3. Suppressions for real chromium bugs that are not yet fixed.
 # These should all be in chromium's bug tracking system (but a few aren't yet).
@@ -2611,8 +2612,8 @@
    bug_386418
    Memcheck:Leak
    fun:_Znw*
-   fun:_ZN4base8internal20PostTaskAndReplyImpl16PostTaskAndReplyERKN15tracked_objects8LocationERKNS_8CallbackIFvvEEESA_
-   fun:_ZN4base10WorkerPool16PostTaskAndReplyERKN15tracked_objects8LocationERKNS_8CallbackIFvvEEES9_b
+   fun:_ZN4base8internal20PostTaskAndReplyImpl16PostTaskAndReplyERKN15tracked_objects8LocationERKNS_8CallbackIF*
+   fun:_ZN4base10WorkerPool16PostTaskAndReplyERKN15tracked_objects8LocationERKNS_8CallbackIF*
    fun:_ZN3net16HostResolverImpl16LoopbackProbeJob*
    fun:_ZN3net16HostResolverImpl*
 }
@@ -2818,7 +2819,7 @@
    bug_431213_a
    Memcheck:Leak
    fun:_Znw*
-   fun:_ZN3gin22CreateFunctionTemplateIF*LocalINS6_16FunctionTemplateEEEPNS6_7IsolateEN4base8CallbackIT_EEi
+   fun:_ZN3gin22CreateFunctionTemplateIF*LocalINS6_16FunctionTemplateEEEPNS6_7IsolateEN4base8CallbackIT*
    fun:_ZN3gin12_GLOBAL__N_114CallbackTraitsIMN*CreateTemplateEPN2v87IsolateES6_
    fun:_ZN3gin21ObjectTemplateBuilder9SetMethodIMN*0_RKN4base16BasicStringPieceISsEERKT_
    fun:_ZN*24GetObjectTemplateBuilderEPN2v87IsolateE
@@ -2827,7 +2828,7 @@
    bug_431213_b
    Memcheck:Leak
    fun:_Znw*
-   fun:_ZN3gin22CreateFunctionTemplateIF*IsolateEN4base8CallbackIT_EEi
+   fun:_ZN3gin22CreateFunctionTemplateIF*IsolateEN4base8CallbackIT*
    fun:_ZN3gin12_GLOBAL__N_114CallbackTraitsIF*
    fun:_ZN3gin21ObjectTemplateBuilder9SetMethod*RKN4base16BasicStringPieceISsEERKT_
    fun:_ZN4mojo2js*GetModuleEPN2v87IsolateE
@@ -2836,7 +2837,7 @@
    bug_431213_c
    Memcheck:Leak
    fun:_Znw*
-   fun:_ZN3gin22CreateFunctionTemplateIF*IsolateEN4base8CallbackIT_EEi
+   fun:_ZN3gin22CreateFunctionTemplateIF*IsolateEN4base8CallbackIT*
    fun:_ZN3gin12_GLOBAL__N_114CallbackTraitsI*
    fun:_ZN3gin21ObjectTemplateBuilder9SetMethod*RKN4base16BasicStringPieceISsEERKT_
    fun:_ZN10extensions19TestServiceProvider24GetObjectTemplateBuilderEPN2v87IsolateE
@@ -2845,7 +2846,7 @@
    bug_431213_d
    Memcheck:Leak
    fun:_Znw*
-   fun:_ZN3gin22CreateFunctionTemplateIF*IsolateEN4base8CallbackIT_EEi
+   fun:_ZN3gin22CreateFunctionTemplateIF*IsolateEN4base8CallbackIT*
    fun:_ZN3gin12_GLOBAL__N_114CallbackTraitsI*
    fun:_ZN3gin21ObjectTemplateBuilder9SetMethod*RKN4base16BasicStringPieceISsEERKT_
    fun:_ZN10extensions12_GLOBAL__N_111TestNatives24GetObjectTemplateBuilderEPN2v87IsolateE
@@ -2854,7 +2855,7 @@
    bug_431213_e
    Memcheck:Leak
    fun:_Znw*
-   fun:_ZN3gin22CreateFunctionTemplateIF*IsolateEN4base8CallbackIT_EEi
+   fun:_ZN3gin22CreateFunctionTemplateIF*IsolateEN4base8CallbackIT*
    fun:_ZN3gin12_GLOBAL__N_114CallbackTraitsIF*
    fun:_ZN3gin21ObjectTemplateBuilder9SetMethodIF*
    fun:_ZN4mojo3edk2js4Core9GetModuleEPN2v87IsolateE
@@ -2866,7 +2867,7 @@
    bug_431213_f
    Memcheck:Leak
    fun:_Znw*
-   fun:_ZN3gin22CreateFunctionTemplateIF*IsolateEN4base8CallbackIT_EEi
+   fun:_ZN3gin22CreateFunctionTemplateIF*IsolateEN4base8CallbackIT*
    fun:_ZN3gin12_GLOBAL__N_114CallbackTraitsIF*
    fun:_ZN3gin21ObjectTemplateBuilder9SetMethodIF*
    fun:_ZN4mojo3edk2js7Support9GetModuleEPN2v87IsolateE
diff --git a/tools/valgrind/memcheck/suppressions_linux.txt b/tools/valgrind/memcheck/suppressions_linux.txt
index 4aa2563..84c410c 100644
--- a/tools/valgrind/memcheck/suppressions_linux.txt
+++ b/tools/valgrind/memcheck/suppressions_linux.txt
@@ -90,7 +90,7 @@
    fun:_ZN4base12_GLOBAL__N_110ThreadFuncEPv
 }
 {
-   b_555798_a
+   bug_555798_a
    Memcheck:Leak
    fun:malloc
    fun:strdup
@@ -100,7 +100,7 @@
    fun:*ExternalClearKeyTestHelper*
 }
 {
-   b_555798_b
+   bug_555798_b
    Memcheck:Leak
    fun:_Znw*
    obj:*
@@ -109,7 +109,7 @@
    fun:dl_open_worker
 }
 {
-   b_569736
+   bug_569736
    Memcheck:Leak
    fun:_Znw*
    obj:*
@@ -117,27 +117,27 @@
    fun:_ZN5media14CdmWrapperImplIN3cdm25ContentDecryptionModule_8EE7DecryptERKNS1_11InputBufferEPNS1_14DecryptedBlockE
 }
 {
-  b_588788
-  Memcheck:Unaddressable
-  ...
-  fun:_ZN5views14AXAuraObjCache14GetFocusedViewEv
-  fun:_ZN5views14AXAuraObjCache8GetFocusEv
-  fun:_ZNK16AXTreeSourceAura11GetTreeDataEv
-  fun:_ZN2ui16AXTreeSerializerIPN5views16AXAuraObjWrapperENS_10AXNodeDataENS_10AXTreeDataEE16SerializeChangesES3_PNS_16AXTreeUpdateBaseIS4_S5_EE
-  fun:_ZN35AXTreeSourceAuraTest_Serialize_Test8TestBodyEv
+   bug_588788
+   Memcheck:Unaddressable
+   ...
+   fun:_ZN5views14AXAuraObjCache14GetFocusedViewEv
+   fun:_ZN5views14AXAuraObjCache8GetFocusEv
+   fun:_ZNK16AXTreeSourceAura11GetTreeDataEv
+   fun:_ZN2ui16AXTreeSerializerIPN5views16AXAuraObjWrapperENS_10AXNodeDataENS_10AXTreeDataEE16SerializeChangesES3_PNS_16AXTreeUpdateBaseIS4_S5_EE
+   fun:_ZN35AXTreeSourceAuraTest_Serialize_Test8TestBodyEv
 }
 {
-  b_588849a
-  Memcheck:Leak
-  fun:_Znw*
-  fun:_ZN4base4BindIMN6syncer15ModelSafeWorkerEFvNS_8CallbackIFvNS1_14ModelSafeGroupEEEEEJPS2_RS6_EEENS3_INS_8internal22MakeUnboundRunTypeImplIT_JDpT0_EE4TypeEEESD_DpOSE_
-  fun:_ZN6syncer15ModelSafeWorker28UnregisterForLoopDestructionEN4base8CallbackIFvNS_14ModelSafeGroupEEEE
-  fun:_ZN12browser_sync20SyncBackendRegistrar8ShutdownEv
+   bug_588849a
+   Memcheck:Leak
+   fun:_Znw*
+   fun:_ZN4base4BindIMN6syncer15ModelSafeWorkerEFvNS_8CallbackIFvNS1_14ModelSafeGroupEEEEEJPS2_RS6_EEENS3_INS_8internal22MakeUnboundRunTypeImplIT_JDpT0_EE4TypeEEESD_DpOSE_
+   fun:_ZN6syncer15ModelSafeWorker28UnregisterForLoopDestructionEN4base8CallbackIFvNS_14ModelSafeGroupEEEE
+   fun:_ZN12browser_sync20SyncBackendRegistrar8ShutdownEv
 }
 {
-  b_588849b
-  Memcheck:Leak
-  fun:_Znw*
-  fun:_ZN30ProfileSyncServiceAutofillTest24CreateDataTypeControllerEN6syncer9ModelTypeE
-  fun:_ZN30ProfileSyncServiceAutofillTest16StartSyncServiceERKN4base8CallbackIFvvEEEbN6syncer9ModelTypeE
+   bug_588849b
+   Memcheck:Leak
+   fun:_Znw*
+   fun:_ZN30ProfileSyncServiceAutofillTest24CreateDataTypeControllerEN6syncer9ModelTypeE
+   fun:_ZN30ProfileSyncServiceAutofillTest16StartSyncServiceERKN4base8CallbackIF*syncer9ModelTypeE
 }
diff --git a/ui/accessibility/ax_tree_data.cc b/ui/accessibility/ax_tree_data.cc
index ef7894f..274da85f 100644
--- a/ui/accessibility/ax_tree_data.cc
+++ b/ui/accessibility/ax_tree_data.cc
@@ -19,6 +19,7 @@
 AXTreeData::AXTreeData()
     : tree_id(-1),
       parent_tree_id(-1),
+      focused_tree_id(-1),
       loaded(false),
       loading_progress(0.0),
       focus_id(-1),
@@ -42,6 +43,8 @@
     result += " tree_id=" + IntToString(tree_id);
   if (parent_tree_id != -1)
     result += " parent_tree_id=" + IntToString(parent_tree_id);
+  if (focused_tree_id != -1)
+    result += " focused_tree_id=" + IntToString(focused_tree_id);
 
   if (!url.empty())
     result += " url=" + url;
@@ -75,6 +78,7 @@
 bool operator==(const AXTreeData& lhs, const AXTreeData& rhs) {
   return (lhs.tree_id == rhs.tree_id &&
           lhs.parent_tree_id == rhs.parent_tree_id &&
+          lhs.focused_tree_id == rhs.focused_tree_id &&
           lhs.url == rhs.url &&
           lhs.title == rhs.title &&
           lhs.mimetype == rhs.mimetype &&
diff --git a/ui/accessibility/ax_tree_data.h b/ui/accessibility/ax_tree_data.h
index 2079dfc..f780415 100644
--- a/ui/accessibility/ax_tree_data.h
+++ b/ui/accessibility/ax_tree_data.h
@@ -38,6 +38,10 @@
   // The ID of the accessibility tree that this tree is contained in, if any.
   int32_t parent_tree_id;
 
+  // The ID of the accessibility tree that has focus. This is typically set
+  // on the root frame in a frame tree.
+  int32_t focused_tree_id;
+
   // Attributes specific to trees that are web frames.
   std::string url;
   std::string title;
diff --git a/ui/arc/BUILD.gn b/ui/arc/BUILD.gn
index 76a4b95e..7b987aa7 100644
--- a/ui/arc/BUILD.gn
+++ b/ui/arc/BUILD.gn
@@ -21,3 +21,21 @@
     "//ui/message_center",
   ]
 }
+
+static_library("ui_arc_unittests") {
+  testonly = true
+  sources = [
+    "notification/arc_notification_manager_unittest.cc",
+    "test/run_all_unittests.cc",
+  ]
+
+  deps = [
+    ":arc",
+    "//base",
+    "//base/test:test_support",
+    "//components/arc:arc_test_support",
+    "//mojo/edk/system",
+    "//mojo/message_pump",
+    "//ui/message_center:test_support",
+  ]
+}
diff --git a/ui/arc/arc.gyp b/ui/arc/arc.gyp
index b0789e1..e1a40a7 100644
--- a/ui/arc/arc.gyp
+++ b/ui/arc/arc.gyp
@@ -8,15 +8,17 @@
   },
   'targets': [
     {
+      # GN: //ui/arc:arc
       'target_name': 'arc',
       'type': 'static_library',
       'include_dirs': [
-        '..',
+        '../..',
       ],
       'dependencies': [
         '../gfx/gfx.gyp:gfx_geometry',
         '../message_center/message_center.gyp:message_center',
         '../../base/base.gyp:base',
+        '../../url/url.gyp:url_lib',
         '../../skia/skia.gyp:skia',
         '../../components/components.gyp:arc_mojo_bindings',
         '../../components/components.gyp:signin_core_account_id',
@@ -28,5 +30,28 @@
         'notification/arc_notification_item.h',
       ],
     },
+    {
+      # GN: //ui/arc:ui_arc_unittests
+      'target_name': 'ui_arc_unittests',
+      'type': '<(gtest_target_type)',
+      'include_dirs': [
+        '../..',
+      ],
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../../base/base.gyp:test_support_base',
+        '../../components/components.gyp:arc_test_support',
+        '../../mojo/mojo_edk.gyp:mojo_system_impl',
+        '../../mojo/mojo_public.gyp:mojo_cpp_bindings',
+        '../../mojo/mojo_public.gyp:mojo_message_pump_lib',
+        '../../testing/gtest.gyp:gtest',
+        '../message_center/message_center.gyp:message_center_test_support',
+        'arc',
+      ],
+      'sources': [
+        'notification/arc_notification_manager_unittest.cc',
+        'test/run_all_unittests.cc',
+      ],
+    },
   ],
 }
diff --git a/ui/arc/notification/arc_notification_manager.cc b/ui/arc/notification/arc_notification_manager.cc
index a43015c..4f65559 100644
--- a/ui/arc/notification/arc_notification_manager.cc
+++ b/ui/arc/notification/arc_notification_manager.cc
@@ -11,8 +11,17 @@
 
 ArcNotificationManager::ArcNotificationManager(ArcBridgeService* bridge_service,
                                                const AccountId& main_profile_id)
+    : ArcNotificationManager(bridge_service,
+                             main_profile_id,
+                             message_center::MessageCenter::Get()) {}
+
+ArcNotificationManager::ArcNotificationManager(
+    ArcBridgeService* bridge_service,
+    const AccountId& main_profile_id,
+    message_center::MessageCenter* message_center)
     : ArcService(bridge_service),
       main_profile_id_(main_profile_id),
+      message_center_(message_center),
       binding_(this) {
   arc_bridge_service()->AddObserver(this);
 }
@@ -50,8 +59,8 @@
   if (it == items_.end()) {
     // Show a notification on the primary loged-in user's desktop.
     // TODO(yoshiki): Reconsider when ARC supports multi-user.
-    ArcNotificationItem* item = new ArcNotificationItem(
-        this, message_center::MessageCenter::Get(), key, main_profile_id_);
+    ArcNotificationItem* item =
+        new ArcNotificationItem(this, message_center_, key, main_profile_id_);
     // TODO(yoshiki): Use emplacement for performance when it's available.
     auto result = items_.insert(std::make_pair(key, make_scoped_ptr(item)));
     DCHECK(result.second);
diff --git a/ui/arc/notification/arc_notification_manager.h b/ui/arc/notification/arc_notification_manager.h
index 4b21719d..27091167 100644
--- a/ui/arc/notification/arc_notification_manager.h
+++ b/ui/arc/notification/arc_notification_manager.h
@@ -13,6 +13,7 @@
 #include "components/arc/common/notifications.mojom.h"
 #include "components/signin/core/account_id/account_id.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "ui/message_center/message_center.h"
 
 namespace arc {
 
@@ -24,6 +25,11 @@
  public:
   ArcNotificationManager(ArcBridgeService* bridge_service,
                          const AccountId& main_profile_id);
+
+  ArcNotificationManager(ArcBridgeService* bridge_service,
+                         const AccountId& main_profile_id,
+                         message_center::MessageCenter* message_center);
+
   ~ArcNotificationManager() override;
 
   // ArcBridgeService::Observer implementation:
@@ -42,6 +48,7 @@
 
  private:
   const AccountId main_profile_id_;
+  message_center::MessageCenter* const message_center_;
 
   using ItemMap =
       std::unordered_map<std::string, scoped_ptr<ArcNotificationItem>>;
diff --git a/ui/arc/notification/arc_notification_manager_unittest.cc b/ui/arc/notification/arc_notification_manager_unittest.cc
new file mode 100644
index 0000000..9e2f010
--- /dev/null
+++ b/ui/arc/notification/arc_notification_manager_unittest.cc
@@ -0,0 +1,170 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "components/arc/test/fake_arc_bridge_instance.h"
+#include "components/arc/test/fake_arc_bridge_service.h"
+#include "components/arc/test/fake_notifications_instance.h"
+#include "mojo/message_pump/message_pump_mojo.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/arc/notification/arc_notification_manager.h"
+#include "ui/message_center/fake_message_center.h"
+
+namespace arc {
+
+namespace {
+
+const char kDummyNotificationKey[] = "DUMMY_NOTIFICATION_KEY";
+
+class MockMessageCenter : public message_center::FakeMessageCenter {
+ public:
+  MockMessageCenter() {}
+  ~MockMessageCenter() override {
+    STLDeleteContainerPointers(
+        visible_notifications_.begin(), visible_notifications_.end());
+  }
+
+  void AddNotification(
+      scoped_ptr<message_center::Notification> notification) override {
+    visible_notifications_.insert(notification.release());
+  }
+
+  void RemoveNotification(const std::string& id, bool by_user) override {
+    for (auto it = visible_notifications_.begin();
+         it != visible_notifications_.end(); it++) {
+      if ((*it)->id() == id) {
+        delete *it;
+        visible_notifications_.erase(it);
+        return;
+      }
+    }
+  }
+
+  const message_center::NotificationList::Notifications&
+  GetVisibleNotifications() override {
+    return visible_notifications_;
+  }
+
+ private:
+  message_center::NotificationList::Notifications visible_notifications_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockMessageCenter);
+};
+
+class ArcBridgeServiceObserver : public ArcBridgeService::Observer {
+ public:
+  ArcBridgeServiceObserver() = default;
+  void OnNotificationsInstanceReady() override { ready_ = true; }
+
+  bool IsReady() { return ready_; }
+
+ private:
+  bool ready_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(ArcBridgeServiceObserver);
+};
+
+}  // anonymous namespace
+
+class ArcNotificationManagerTest : public testing::Test {
+ public:
+  ArcNotificationManagerTest()
+      : loop_(mojo::common::MessagePumpMojo::Create()) {}
+  ~ArcNotificationManagerTest() override { loop_.RunUntilIdle(); }
+
+ protected:
+  FakeArcBridgeService* service() { return service_.get(); }
+  FakeNotificationsInstance* arc_notifications_instance() {
+    return arc_notifications_instance_.get();
+  }
+  ArcNotificationManager* arc_notification_manager() {
+    return arc_notification_manager_.get();
+  }
+  MockMessageCenter* message_center() { return message_center_.get(); }
+
+  std::string CreateNotification() {
+    auto data = ArcNotificationData::New();
+    data->key = kDummyNotificationKey;
+    data->title = "TITLE";
+    data->message = "MESSAGE";
+
+    std::vector<unsigned char> icon_data;
+    data->icon_data.Swap(&icon_data);
+
+    arc_notification_manager()->OnNotificationPosted(std::move(data));
+
+    return std::string(kDummyNotificationKey);
+  }
+
+ private:
+  base::MessageLoop loop_;
+  scoped_ptr<FakeArcBridgeService> service_;
+  scoped_ptr<FakeNotificationsInstance> arc_notifications_instance_;
+  scoped_ptr<ArcNotificationManager> arc_notification_manager_;
+  scoped_ptr<MockMessageCenter> message_center_;
+
+  void SetUp() override {
+    NotificationsInstancePtr arc_notifications_instance;
+    arc_notifications_instance_.reset(
+        new FakeNotificationsInstance(GetProxy(&arc_notifications_instance)));
+    service_.reset(new FakeArcBridgeService());
+    message_center_.reset(new MockMessageCenter());
+
+    arc_notification_manager_.reset(new ArcNotificationManager(
+        service(), EmptyAccountId(), message_center_.get()));
+
+    ArcBridgeServiceObserver observer;
+    service_->AddObserver(&observer);
+    service_->OnNotificationsInstanceReady(
+        std::move(arc_notifications_instance));
+
+    while (!observer.IsReady())
+      loop_.RunUntilIdle();
+
+    service_->RemoveObserver(&observer);
+  }
+
+  void TearDown() override {
+    arc_notification_manager_.reset();
+    message_center_.reset();
+    service_.reset();
+    arc_notifications_instance_.reset();
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(ArcNotificationManagerTest);
+};
+
+TEST_F(ArcNotificationManagerTest, NotificationCreatedAndRemoved) {
+  EXPECT_EQ(0u, message_center()->GetVisibleNotifications().size());
+  std::string key = CreateNotification();
+  EXPECT_EQ(1u, message_center()->GetVisibleNotifications().size());
+
+  arc_notification_manager()->OnNotificationRemoved(key);
+
+  EXPECT_EQ(0u, message_center()->GetVisibleNotifications().size());
+}
+
+TEST_F(ArcNotificationManagerTest, NotificationRemovedByChrome) {
+  service()->SetReady();
+  EXPECT_EQ(0u, message_center()->GetVisibleNotifications().size());
+  std::string key = CreateNotification();
+  EXPECT_EQ(1u, message_center()->GetVisibleNotifications().size());
+
+  {
+    message_center::Notification* notification =
+        *message_center()->GetVisibleNotifications().begin();
+    notification->delegate()->Close(true /* by_user */);
+    // |notification| gets stale here.
+  }
+
+  arc_notifications_instance()->WaitForIncomingMethodCall();
+
+  ASSERT_EQ(1u, arc_notifications_instance()->events().size());
+  EXPECT_EQ(key, arc_notifications_instance()->events().at(0).first);
+  EXPECT_EQ(ArcNotificationEvent::CLOSED,
+            arc_notifications_instance()->events().at(0).second);
+}
+
+}  // namespace arc
diff --git a/ui/arc/test/run_all_unittests.cc b/ui/arc/test/run_all_unittests.cc
new file mode 100644
index 0000000..92e28e4b
--- /dev/null
+++ b/ui/arc/test/run_all_unittests.cc
@@ -0,0 +1,17 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/test/launcher/unit_test_launcher.h"
+#include "base/test/test_suite.h"
+#include "mojo/edk/embedder/embedder.h"
+
+int main(int argc, char** argv) {
+  base::TestSuite test_suite(argc, argv);
+
+  mojo::edk::Init();
+  return base::LaunchUnitTests(
+      argc, argv,
+      base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));
+}
diff --git a/ui/events/test/cocoa_test_event_utils.h b/ui/events/test/cocoa_test_event_utils.h
index dfeceb2..6dd6944b 100644
--- a/ui/events/test/cocoa_test_event_utils.h
+++ b/ui/events/test/cocoa_test_event_utils.h
@@ -9,6 +9,7 @@
 
 #import <objc/objc-class.h>
 
+#include "ui/events/keycodes/dom/dom_key.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
 namespace cocoa_test_event_utils {
@@ -67,7 +68,8 @@
 NSEvent* SynthesizeKeyEvent(NSWindow* window,
                             bool keyDown,
                             ui::KeyboardCode keycode,
-                            NSUInteger flags);
+                            NSUInteger flags,
+                            ui::DomKey dom_key = ui::DomKey::NONE);
 
 }  // namespace cocoa_test_event_utils
 
diff --git a/ui/events/test/cocoa_test_event_utils.mm b/ui/events/test/cocoa_test_event_utils.mm
index 6c7819f..9810d58 100644
--- a/ui/events/test/cocoa_test_event_utils.mm
+++ b/ui/events/test/cocoa_test_event_utils.mm
@@ -190,7 +190,8 @@
 NSEvent* SynthesizeKeyEvent(NSWindow* window,
                             bool keyDown,
                             ui::KeyboardCode keycode,
-                            NSUInteger flags) {
+                            NSUInteger flags,
+                            ui::DomKey dom_key) {
   // If caps lock is set for an alpha keycode, treat it as if shift was pressed.
   // Note on Mac (unlike other platforms) shift while caps is down does not go
   // back to lowercase.
@@ -210,6 +211,11 @@
   if (macKeycode < 0)
     return nil;
 
+  // If an explicit unicode character is provided, use that instead of the one
+  // derived from the keycode.
+  if (dom_key.IsCharacter())
+    shifted_character = dom_key.ToCharacter();
+
   // Note that, in line with AppKit's documentation (and tracing "real" events),
   // -[NSEvent charactersIngoringModifiers]" are "the characters generated by
   // the receiving key event as if no modifier key (except for Shift)".
diff --git a/ui/ozone/platform/wayland/fake_server.cc b/ui/ozone/platform/wayland/fake_server.cc
index 2afc547..be40689 100644
--- a/ui/ozone/platform/wayland/fake_server.cc
+++ b/ui/ozone/platform/wayland/fake_server.cc
@@ -10,6 +10,7 @@
 
 #include "base/bind.h"
 #include "base/files/scoped_file.h"
+#include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 
 namespace wl {
@@ -274,6 +275,7 @@
       resume_event_(false, false) {}
 
 FakeServer::~FakeServer() {
+  Resume();
   Stop();
 }
 
@@ -312,10 +314,6 @@
   return true;
 }
 
-void FakeServer::Flush() {
-  wl_display_flush_clients(display_.get());
-}
-
 void FakeServer::Pause() {
   task_runner()->PostTask(
       FROM_HERE, base::Bind(&FakeServer::DoPause, base::Unretained(this)));
@@ -323,10 +321,13 @@
 }
 
 void FakeServer::Resume() {
+  if (display_)
+    wl_display_flush_clients(display_.get());
   resume_event_.Signal();
 }
 
 void FakeServer::DoPause() {
+  base::RunLoop().RunUntilIdle();
   pause_event_.Signal();
   resume_event_.Wait();
 }
diff --git a/ui/ozone/platform/wayland/fake_server.h b/ui/ozone/platform/wayland/fake_server.h
index befde1c..5c5b471 100644
--- a/ui/ozone/platform/wayland/fake_server.h
+++ b/ui/ozone/platform/wayland/fake_server.h
@@ -146,9 +146,10 @@
   // wl_display_connect).
   bool Start();
 
-  void Flush();
-
+  // Pause the server when it becomes idle.
   void Pause();
+
+  // Resume the server after flushing client connections.
   void Resume();
 
   template <typename T>
diff --git a/ui/ozone/platform/wayland/wayland_display.cc b/ui/ozone/platform/wayland/wayland_display.cc
index 1adc88e0..fcd841f 100644
--- a/ui/ozone/platform/wayland/wayland_display.cc
+++ b/ui/ozone/platform/wayland/wayland_display.cc
@@ -6,6 +6,7 @@
 
 #include <xdg-shell-unstable-v5-client-protocol.h>
 
+#include "base/bind.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
 #include "ui/ozone/platform/wayland/wayland_object.h"
@@ -60,9 +61,29 @@
   return true;
 }
 
-void WaylandDisplay::Flush() {
+bool WaylandDisplay::StartProcessingEvents() {
+  if (watching_)
+    return true;
+
   DCHECK(display_);
   wl_display_flush(display_.get());
+
+  DCHECK(base::MessageLoopForUI::IsCurrent());
+  if (!base::MessageLoopForUI::current()->WatchFileDescriptor(
+          wl_display_get_fd(display_.get()), true,
+          base::MessagePumpLibevent::WATCH_READ, &controller_, this))
+    return false;
+
+  watching_ = true;
+  return true;
+}
+
+void WaylandDisplay::ScheduleFlush() {
+  if (scheduled_flush_ || !watching_)
+    return;
+  base::MessageLoopForUI::current()->task_runner()->PostTask(
+      FROM_HERE, base::Bind(&WaylandDisplay::Flush, base::Unretained(this)));
+  scheduled_flush_ = true;
 }
 
 WaylandWindow* WaylandDisplay::GetWindow(gfx::AcceleratedWidget widget) {
@@ -80,15 +101,12 @@
 }
 
 void WaylandDisplay::OnDispatcherListChanged() {
-  if (watching_)
-    return;
+  StartProcessingEvents();
+}
 
-  DCHECK(display_);
-  DCHECK(base::MessageLoopForUI::IsCurrent());
-  base::MessageLoopForUI::current()->WatchFileDescriptor(
-      wl_display_get_fd(display_.get()), true,
-      base::MessagePumpLibevent::WATCH_READ, &controller_, this);
-  watching_ = true;
+void WaylandDisplay::Flush() {
+  wl_display_flush(display_.get());
+  scheduled_flush_ = false;
 }
 
 void WaylandDisplay::OnFileCanReadWithoutBlocking(int fd) {
@@ -131,6 +149,8 @@
     xdg_shell_use_unstable_version(display->shell_.get(),
                                    XDG_SHELL_VERSION_CURRENT);
   }
+
+  display->ScheduleFlush();
 }
 
 // static
@@ -142,7 +162,9 @@
 
 // static
 void WaylandDisplay::Ping(void* data, xdg_shell* shell, uint32_t serial) {
+  WaylandDisplay* display = static_cast<WaylandDisplay*>(data);
   xdg_shell_pong(shell, serial);
+  display->ScheduleFlush();
 }
 
 }  // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_display.h b/ui/ozone/platform/wayland/wayland_display.h
index 5a6936b..bfdf5d1 100644
--- a/ui/ozone/platform/wayland/wayland_display.h
+++ b/ui/ozone/platform/wayland/wayland_display.h
@@ -23,9 +23,10 @@
   ~WaylandDisplay() override;
 
   bool Initialize();
+  bool StartProcessingEvents();
 
-  // Flushes the Wayland connection.
-  void Flush();
+  // Schedules a flush of the Wayland connection.
+  void ScheduleFlush();
 
   wl_display* display() { return display_.get(); }
   wl_compositor* compositor() { return compositor_.get(); }
@@ -37,6 +38,8 @@
   void RemoveWindow(gfx::AcceleratedWidget widget);
 
  private:
+  void Flush();
+
   // PlatformEventSource
   void OnDispatcherListChanged() override;
 
@@ -63,6 +66,7 @@
   wl::Object<wl_shm> shm_;
   wl::Object<xdg_shell> shell_;
 
+  bool scheduled_flush_ = false;
   bool watching_ = false;
   base::MessagePumpLibevent::FileDescriptorWatcher controller_;
 
diff --git a/ui/ozone/platform/wayland/wayland_display_unittest.cc b/ui/ozone/platform/wayland/wayland_display_unittest.cc
index a50f83f..3b37154a 100644
--- a/ui/ozone/platform/wayland/wayland_display_unittest.cc
+++ b/ui/ozone/platform/wayland/wayland_display_unittest.cc
@@ -5,6 +5,7 @@
 #include <wayland-server-core.h>
 #include <xdg-shell-unstable-v5-server-protocol.h>
 
+#include "base/run_loop.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/ozone/platform/wayland/fake_server.h"
 #include "ui/ozone/platform/wayland/wayland_display.h"
@@ -12,31 +13,36 @@
 namespace ui {
 
 TEST(WaylandDisplayTest, UseUnstableVersion) {
+  base::MessageLoopForUI message_loop;
   wl::FakeServer server;
   EXPECT_CALL(*server.xdg_shell(),
               UseUnstableVersion(XDG_SHELL_VERSION_CURRENT));
   ASSERT_TRUE(server.Start());
   WaylandDisplay display;
   ASSERT_TRUE(display.Initialize());
-  wl_display_roundtrip(display.display());
+  display.StartProcessingEvents();
+
+  base::RunLoop().RunUntilIdle();
+  server.Pause();
 }
 
 TEST(WaylandDisplayTest, Ping) {
+  base::MessageLoopForUI message_loop;
   wl::FakeServer server;
   ASSERT_TRUE(server.Start());
   WaylandDisplay display;
   ASSERT_TRUE(display.Initialize());
-  wl_display_roundtrip(display.display());
+  display.StartProcessingEvents();
 
+  base::RunLoop().RunUntilIdle();
   server.Pause();
 
   xdg_shell_send_ping(server.xdg_shell()->resource(), 1234);
   EXPECT_CALL(*server.xdg_shell(), Pong(1234));
-  server.Flush();
 
   server.Resume();
-
-  wl_display_roundtrip(display.display());
+  base::RunLoop().RunUntilIdle();
+  server.Pause();
 }
 
 }  // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_surface_factory.cc b/ui/ozone/platform/wayland/wayland_surface_factory.cc
index f8d8421..545016f 100644
--- a/ui/ozone/platform/wayland/wayland_surface_factory.cc
+++ b/ui/ozone/platform/wayland/wayland_surface_factory.cc
@@ -108,7 +108,7 @@
                     damage.height());
   wl_surface_attach(surface, buffer_.get(), 0, 0);
   wl_surface_commit(surface);
-  display_->Flush();
+  display_->ScheduleFlush();
 }
 
 scoped_ptr<gfx::VSyncProvider> WaylandCanvasSurface::CreateVSyncProvider() {
diff --git a/ui/ozone/platform/wayland/wayland_test.cc b/ui/ozone/platform/wayland/wayland_test.cc
index 85c897d..3d3fec7b 100644
--- a/ui/ozone/platform/wayland/wayland_test.cc
+++ b/ui/ozone/platform/wayland/wayland_test.cc
@@ -4,6 +4,8 @@
 
 #include "ui/ozone/platform/wayland/wayland_test.h"
 
+#include "base/run_loop.h"
+
 using ::testing::SaveArg;
 using ::testing::_;
 
@@ -17,28 +19,38 @@
 void WaylandTest::SetUp() {
   ASSERT_TRUE(server.Start());
   ASSERT_TRUE(display.Initialize());
+  display.StartProcessingEvents();
   EXPECT_CALL(delegate, OnAcceleratedWidgetAvailable(_, _))
       .WillOnce(SaveArg<0>(&widget));
   ASSERT_TRUE(window.Initialize());
   ASSERT_NE(widget, gfx::kNullAcceleratedWidget);
-  wl_display_roundtrip(display.display());
 
+  // Wait for the client to flush all pending requests from initialization.
+  base::RunLoop().RunUntilIdle();
+
+  // Pause the server after it has responded to all incoming events.
   server.Pause();
 
   surface = server.GetObject<wl::MockSurface>(widget);
   ASSERT_TRUE(surface);
+
   initialized = true;
 }
 
 void WaylandTest::TearDown() {
-  server.Resume();
   if (initialized)
-    wl_display_roundtrip(display.display());
+    Sync();
 }
 
 void WaylandTest::Sync() {
+  // Resume the server, flushing its pending events.
   server.Resume();
-  wl_display_roundtrip(display.display());
+
+  // Wait for the client to finish processing these events.
+  base::RunLoop().RunUntilIdle();
+
+  // Pause the server, after it has finished processing any follow-up requests
+  // from the client.
   server.Pause();
 }
 
diff --git a/ui/ozone/platform/wayland/wayland_test.h b/ui/ozone/platform/wayland/wayland_test.h
index 7cba490..59a56a9 100644
--- a/ui/ozone/platform/wayland/wayland_test.h
+++ b/ui/ozone/platform/wayland/wayland_test.h
@@ -28,6 +28,7 @@
  private:
   bool initialized = false;
   wl::FakeServer server;
+  base::MessageLoopForUI message_loop;
 
  protected:
   wl::MockSurface* surface;
diff --git a/ui/ozone/platform/wayland/wayland_window.cc b/ui/ozone/platform/wayland/wayland_window.cc
index e28aacf..b64f0bc 100644
--- a/ui/ozone/platform/wayland/wayland_window.cc
+++ b/ui/ozone/platform/wayland/wayland_window.cc
@@ -41,6 +41,7 @@
     return false;
   }
   xdg_surface_add_listener(xdg_surface_.get(), &xdg_surface_listener, this);
+  display_->ScheduleFlush();
 
   display_->AddWindow(surface_.id(), this);
   delegate_->OnAcceleratedWidgetAvailable(surface_.id(), 1.f);
@@ -56,6 +57,7 @@
   DCHECK(xdg_surface_);
   xdg_surface_ack_configure(xdg_surface_.get(), pending_configure_serial_);
   pending_bounds_ = gfx::Rect();
+  display_->ScheduleFlush();
 }
 
 void WaylandWindow::Show() {}
@@ -82,6 +84,7 @@
 void WaylandWindow::SetTitle(const base::string16& title) {
   DCHECK(xdg_surface_);
   xdg_surface_set_title(xdg_surface_.get(), UTF16ToUTF8(title).c_str());
+  display_->ScheduleFlush();
 }
 
 void WaylandWindow::SetCapture() {
@@ -99,16 +102,19 @@
 void WaylandWindow::Maximize() {
   DCHECK(xdg_surface_);
   xdg_surface_set_maximized(xdg_surface_.get());
+  display_->ScheduleFlush();
 }
 
 void WaylandWindow::Minimize() {
   DCHECK(xdg_surface_);
   xdg_surface_set_minimized(xdg_surface_.get());
+  display_->ScheduleFlush();
 }
 
 void WaylandWindow::Restore() {
   DCHECK(xdg_surface_);
   xdg_surface_unset_maximized(xdg_surface_.get());
+  display_->ScheduleFlush();
 }
 
 void WaylandWindow::SetCursor(PlatformCursor cursor) {
diff --git a/ui/ozone/platform/wayland/wayland_window_unittest.cc b/ui/ozone/platform/wayland/wayland_window_unittest.cc
index 93c8aadf..1b1cad7 100644
--- a/ui/ozone/platform/wayland/wayland_window_unittest.cc
+++ b/ui/ozone/platform/wayland/wayland_window_unittest.cc
@@ -5,6 +5,7 @@
 #include <wayland-server-core.h>
 #include <xdg-shell-unstable-v5-server-protocol.h>
 
+#include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -67,13 +68,8 @@
 
   // Make sure that the implementation does not call OnBoundsChanged for each
   // configure event if it receives multiple in a row.
-  EXPECT_CALL(delegate, OnBoundsChanged(_)).Times(0);
-  Sync();
-  Mock::VerifyAndClearExpectations(&delegate);
-
   EXPECT_CALL(delegate, OnBoundsChanged(Eq(gfx::Rect(0, 0, 1500, 1000))));
   EXPECT_CALL(*xdg_surface, AckConfigure(13));
-  window.ApplyPendingBounds();
 }
 
 }  // namespace ui
diff --git a/ui/views/bubble/bubble_dialog_delegate.cc b/ui/views/bubble/bubble_dialog_delegate.cc
index dfbf2eaa..4fbc703 100644
--- a/ui/views/bubble/bubble_dialog_delegate.cc
+++ b/ui/views/bubble/bubble_dialog_delegate.cc
@@ -83,6 +83,10 @@
   return bubble_widget;
 }
 
+BubbleDialogDelegateView* BubbleDialogDelegateView::AsBubbleDialogDelegate() {
+  return this;
+}
+
 bool BubbleDialogDelegateView::ShouldShowCloseButton() const {
   return false;
 }
@@ -208,8 +212,7 @@
 
 BubbleDialogDelegateView::BubbleDialogDelegateView(View* anchor_view,
                                                    BubbleBorder::Arrow arrow)
-    : close_on_esc_(true),
-      close_on_deactivate_(true),
+    : close_on_deactivate_(true),
       anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()),
       anchor_widget_(NULL),
       arrow_(arrow),
@@ -226,7 +229,6 @@
       close_reason_(CloseReason::UNKNOWN) {
   if (anchor_view)
     SetAnchorView(anchor_view);
-  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
   UpdateColorsFromTheme(GetNativeTheme());
 }
 
@@ -244,15 +246,6 @@
   return rb.GetFontList(ui::ResourceBundle::MediumFont);
 }
 
-bool BubbleDialogDelegateView::AcceleratorPressed(
-    const ui::Accelerator& accelerator) {
-  if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE)
-    return false;
-  close_reason_ = CloseReason::ESCAPE;
-  GetWidget()->Close();
-  return true;
-}
-
 void BubbleDialogDelegateView::OnNativeThemeChanged(
     const ui::NativeTheme* theme) {
   UpdateColorsFromTheme(theme);
diff --git a/ui/views/bubble/bubble_dialog_delegate.h b/ui/views/bubble/bubble_dialog_delegate.h
index fc61adc..2efe93e 100644
--- a/ui/views/bubble/bubble_dialog_delegate.h
+++ b/ui/views/bubble/bubble_dialog_delegate.h
@@ -30,7 +30,6 @@
 
   enum class CloseReason {
     DEACTIVATION,
-    ESCAPE,
     CLOSE_BUTTON,
     UNKNOWN,
   };
@@ -41,6 +40,7 @@
   static Widget* CreateBubble(BubbleDialogDelegateView* bubble_delegate);
 
   // WidgetDelegateView overrides:
+  BubbleDialogDelegateView* AsBubbleDialogDelegate() override;
   bool ShouldShowCloseButton() const override;
   ClientView* CreateClientView(Widget* widget) override;
   NonClientFrameView* CreateNonClientFrameView(Widget* widget) override;
@@ -56,9 +56,6 @@
   void OnWidgetBoundsChanged(Widget* widget,
                              const gfx::Rect& new_bounds) override;
 
-  bool close_on_esc() const { return close_on_esc_; }
-  void set_close_on_esc(bool close_on_esc) { close_on_esc_ = close_on_esc; }
-
   bool close_on_deactivate() const { return close_on_deactivate_; }
   void set_close_on_deactivate(bool close) { close_on_deactivate_ = close; }
 
@@ -134,7 +131,6 @@
   virtual const gfx::FontList& GetTitleFontList() const;
 
   // View overrides:
-  bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
   void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
 
   // Perform view initialization on the contents for bubble sizing.
@@ -165,8 +161,7 @@
   // Handles widget visibility changes.
   void HandleVisibilityChanged(Widget* widget, bool visible);
 
-  // Flags controlling bubble closure on the escape key and deactivation.
-  bool close_on_esc_;
+  // A flag controlling bubble closure on deactivation.
   bool close_on_deactivate_;
 
   // The view and widget to which this bubble is anchored. Since an anchor view
diff --git a/ui/views/mus/native_widget_mus.cc b/ui/views/mus/native_widget_mus.cc
index c7ab681b..2a25edd 100644
--- a/ui/views/mus/native_widget_mus.cc
+++ b/ui/views/mus/native_widget_mus.cc
@@ -481,7 +481,8 @@
 }
 
 void NativeWidgetMus::InitModalType(ui::ModalType modal_type) {
-  // NOTIMPLEMENTED();
+  if (modal_type != ui::MODAL_TYPE_NONE)
+    window_->SetModal();
 }
 
 gfx::Rect NativeWidgetMus::GetWindowBoundsInScreen() const {
diff --git a/ui/views/test/event_generator_delegate_mac.mm b/ui/views/test/event_generator_delegate_mac.mm
index 6c371e4..44e08a5 100644
--- a/ui/views/test/event_generator_delegate_mac.mm
+++ b/ui/views/test/event_generator_delegate_mac.mm
@@ -363,7 +363,7 @@
   NSUInteger modifiers = EventFlagsToModifiers(event->flags());
   NSEvent* ns_event = cocoa_test_event_utils::SynthesizeKeyEvent(
       window_, event->type() == ui::ET_KEY_PRESSED, event->key_code(),
-      modifiers);
+      modifiers, event->is_char() ? event->GetDomKey() : ui::DomKey::NONE);
   if (owner_->targeting_application()) {
     [NSApp sendEvent:ns_event];
     return;
diff --git a/ui/views/widget/widget_delegate.cc b/ui/views/widget/widget_delegate.cc
index e62aa928..f10e840 100644
--- a/ui/views/widget/widget_delegate.cc
+++ b/ui/views/widget/widget_delegate.cc
@@ -32,15 +32,19 @@
 }
 
 View* WidgetDelegate::GetInitiallyFocusedView() {
-  return NULL;
+  return nullptr;
 }
 
 BubbleDelegateView* WidgetDelegate::AsBubbleDelegate() {
-  return NULL;
+  return nullptr;
+}
+
+BubbleDialogDelegateView* WidgetDelegate::AsBubbleDialogDelegate() {
+  return nullptr;
 }
 
 DialogDelegate* WidgetDelegate::AsDialogDelegate() {
-  return NULL;
+  return nullptr;
 }
 
 bool WidgetDelegate::CanResize() const {
diff --git a/ui/views/widget/widget_delegate.h b/ui/views/widget/widget_delegate.h
index 660313d..0ec02150 100644
--- a/ui/views/widget/widget_delegate.h
+++ b/ui/views/widget/widget_delegate.h
@@ -19,6 +19,7 @@
 }
 
 namespace views {
+class BubbleDialogDelegateView;
 class BubbleDelegateView;
 class ClientView;
 class DialogDelegate;
@@ -51,6 +52,7 @@
   virtual View* GetInitiallyFocusedView();
 
   virtual BubbleDelegateView* AsBubbleDelegate();
+  virtual BubbleDialogDelegateView* AsBubbleDialogDelegate();
   virtual DialogDelegate* AsDialogDelegate();
 
   // Returns true if the window can be resized.
diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc
index ea23fed..5b5db8b 100644
--- a/ui/views/window/dialog_client_view.cc
+++ b/ui/views/window/dialog_client_view.cc
@@ -61,7 +61,11 @@
       ok_button_(NULL),
       cancel_button_(NULL),
       extra_view_(NULL),
-      delegate_allowed_close_(false) {}
+      delegate_allowed_close_(false) {
+  // Doing this now ensures this accelerator will have lower priority than
+  // one set by the contents view.
+  AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
+}
 
 DialogClientView::~DialogClientView() {
 }
@@ -84,7 +88,6 @@
 
 void DialogClientView::UpdateDialogButtons() {
   const int buttons = GetDialogDelegate()->GetDialogButtons();
-  ui::Accelerator escape(ui::VKEY_ESCAPE, ui::EF_NONE);
 
   if (buttons & ui::DIALOG_BUTTON_OK) {
     if (!ok_button_) {
@@ -101,7 +104,6 @@
   if (buttons & ui::DIALOG_BUTTON_CANCEL) {
     if (!cancel_button_) {
       cancel_button_ = CreateDialogButton(ui::DIALOG_BUTTON_CANCEL);
-      cancel_button_->AddAccelerator(escape);
       AddChildView(cancel_button_);
     }
 
@@ -110,12 +112,6 @@
     delete cancel_button_;
     cancel_button_ = NULL;
   }
-
-  // Use the escape key to close the window if there is no cancel button.
-  if (!cancel_button_)
-    AddAccelerator(escape);
-  else
-    ResetAccelerators();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -214,6 +210,11 @@
 
 bool DialogClientView::AcceleratorPressed(const ui::Accelerator& accelerator) {
   DCHECK_EQ(accelerator.key_code(), ui::VKEY_ESCAPE);
+
+  // If there's a cancel button, it handles escape.
+  if (cancel_button_)
+    return cancel_button_->AcceleratorPressed(accelerator);
+
   GetWidget()->Close();
   return true;
 }
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc
index f74f5a1..6152071 100644
--- a/ui/views/window/dialog_delegate.cc
+++ b/ui/views/window/dialog_delegate.cc
@@ -29,11 +29,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 // DialogDelegate:
 
-DialogDelegate::DialogDelegate() : supports_new_style_(true) {
-}
+DialogDelegate::DialogDelegate() : supports_new_style_(true) {}
 
-DialogDelegate::~DialogDelegate() {
-}
+DialogDelegate::~DialogDelegate() {}
 
 // static
 Widget* DialogDelegate::CreateDialogWidget(WidgetDelegate* delegate,
diff --git a/ui/views/window/dialog_delegate_unittest.cc b/ui/views/window/dialog_delegate_unittest.cc
index 124e0e4..df9d192 100644
--- a/ui/views/window/dialog_delegate_unittest.cc
+++ b/ui/views/window/dialog_delegate_unittest.cc
@@ -33,11 +33,20 @@
         canceled_(false),
         accepted_(false),
         closeable_(false),
-        last_pressed_button_(NULL) {
+        last_pressed_button_(nullptr),
+        should_handle_escape_(false) {
     AddChildView(input_);
   }
   ~TestDialog() override {}
 
+  void Init() {
+    // Add the accelerator before being added to the widget hierarchy (before
+    // DCV has registered its accelerator) to make sure accelerator handling is
+    // not dependent on the order of AddAccelerator calls.
+    EXPECT_FALSE(GetWidget());
+    AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
+  }
+
   // WidgetDelegate overrides:
   bool ShouldShowWindowTitle() const override {
     return !title_.empty();
@@ -55,6 +64,9 @@
 
   // DialogDelegateView overrides:
   gfx::Size GetPreferredSize() const override { return gfx::Size(200, 200); }
+  bool AcceleratorPressed(const ui::Accelerator& accelerator) override {
+    return should_handle_escape_;
+  }
   base::string16 GetWindowTitle() const override { return title_; }
   View* GetInitiallyFocusedView() override { return input_; }
   bool UseNewStyleForThisDialog() const override { return true; }
@@ -72,7 +84,7 @@
     EXPECT_EQ(accepted, accepted_);
     accepted_ = false;
     EXPECT_EQ(last_pressed, last_pressed_button_);
-    last_pressed_button_ = NULL;
+    last_pressed_button_ = nullptr;
   }
 
   void TearDown() {
@@ -81,6 +93,9 @@
   }
 
   void set_title(const base::string16& title) { title_ = title; }
+  void set_should_handle_escape(bool should_handle_escape) {
+    should_handle_escape_ = should_handle_escape;
+  }
 
   views::Textfield* input() { return input_; }
 
@@ -92,19 +107,21 @@
   bool closeable_;
   Button* last_pressed_button_;
   base::string16 title_;
+  bool should_handle_escape_;
 
   DISALLOW_COPY_AND_ASSIGN(TestDialog);
 };
 
 class DialogTest : public ViewsTestBase {
  public:
-  DialogTest() : dialog_(NULL) {}
+  DialogTest() : dialog_(nullptr) {}
   ~DialogTest() override {}
 
   void SetUp() override {
     ViewsTestBase::SetUp();
     dialog_ = new TestDialog();
-    DialogDelegate::CreateDialogWidget(dialog_, GetContext(), NULL)->Show();
+    dialog_->Init();
+    DialogDelegate::CreateDialogWidget(dialog_, GetContext(), nullptr)->Show();
   }
 
   void TearDown() override {
@@ -144,23 +161,28 @@
   const ui::KeyEvent return_event(
       ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE);
   SimulateKeyEvent(return_event);
-  dialog()->CheckAndResetStates(false, true, NULL);
+  dialog()->CheckAndResetStates(false, true, nullptr);
   const ui::KeyEvent escape_event(
       ui::ET_KEY_PRESSED, ui::VKEY_ESCAPE, ui::EF_NONE);
   SimulateKeyEvent(escape_event);
-  dialog()->CheckAndResetStates(true, false, NULL);
+  dialog()->CheckAndResetStates(true, false, nullptr);
 
   // Check ok and cancel button behavior on a directed return key events.
   ok_button->OnKeyPressed(return_event);
-  dialog()->CheckAndResetStates(false, true, NULL);
+  dialog()->CheckAndResetStates(false, true, nullptr);
   cancel_button->OnKeyPressed(return_event);
-  dialog()->CheckAndResetStates(true, false, NULL);
+  dialog()->CheckAndResetStates(true, false, nullptr);
 
   // Check that return accelerators cancel dialogs if cancel is focused.
   cancel_button->RequestFocus();
   EXPECT_EQ(cancel_button, dialog()->GetFocusManager()->GetFocusedView());
   SimulateKeyEvent(return_event);
-  dialog()->CheckAndResetStates(true, false, NULL);
+  dialog()->CheckAndResetStates(true, false, nullptr);
+
+  // Check that escape can be overridden.
+  dialog()->set_should_handle_escape(true);
+  SimulateKeyEvent(escape_event);
+  dialog()->CheckAndResetStates(false, false, nullptr);
 }
 
 TEST_F(DialogTest, RemoveDefaultButton) {
@@ -224,7 +246,7 @@
 TEST_F(DialogTest, BoundsAccommodateTitle) {
   TestDialog* dialog2(new TestDialog());
   dialog2->set_title(base::ASCIIToUTF16("Title"));
-  DialogDelegate::CreateDialogWidget(dialog2, GetContext(), NULL);
+  DialogDelegate::CreateDialogWidget(dialog2, GetContext(), nullptr);
 
   // Titled dialogs have taller initial frame bounds than untitled dialogs.
   View* frame1 = dialog()->GetWidget()->non_client_view()->frame_view();