diff --git a/DEPS b/DEPS
index def7415..02f1023 100644
--- a/DEPS
+++ b/DEPS
@@ -43,7 +43,7 @@
   # 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': '4e8d71c0d2d36db26197d48ae943c15807674653',
+  'v8_revision': 'b8ad5b1f8f374f22e98bb528e67156e9239fa696',
   # 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.
@@ -190,7 +190,7 @@
    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'f962bcb6a8aed397bb2d418527a4e4a23f5ab955',
 
   'src/third_party/libjingle/source/talk':
-    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '5a1f5b5548e30780dcb5211bcdf8ce4f4a937838', # commit position 10776
+    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '223d8ffb60e2f1e10af047a95480716997df860c', # commit position 10790
 
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/usrsctplib.git' + '@' + '36444a999739e9e408f8f587cb4c3ffeef2e50ac', # from svn revision 9215
@@ -214,7 +214,7 @@
    Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
 
   'src/third_party/webrtc':
-    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'dbb9f9bf2684ac070e7f6b8807526498bfb4a115', # commit position 10778
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '57ea0a4064d963a7357070105070969417fdb3f9', # commit position 10796
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
diff --git a/base/trace_event/common/trace_event_common.h b/base/trace_event/common/trace_event_common.h
index 16a9a37..cae3670 100644
--- a/base/trace_event/common/trace_event_common.h
+++ b/base/trace_event/common/trace_event_common.h
@@ -484,6 +484,20 @@
                            static_cast<int>(value1_val), value2_name,       \
                            static_cast<int>(value2_val))
 
+// Similar to TRACE_COUNTERx, but with a custom |timestamp| provided.
+#define TRACE_COUNTER_WITH_TIMESTAMP1(category_group, name, timestamp, value) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                    \
+      TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp,             \
+      TRACE_EVENT_FLAG_NONE, "value", static_cast<int>(value))
+
+#define TRACE_COUNTER_WITH_TIMESTAMP2(category_group, name, timestamp,      \
+                                      value1_name, value1_val, value2_name, \
+                                      value2_val)                           \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                  \
+      TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp,           \
+      TRACE_EVENT_FLAG_NONE, value1_name, static_cast<int>(value1_val),     \
+      value2_name, static_cast<int>(value2_val))
+
 // Records the value of a counter called "name" immediately. Value
 // must be representable as a 32 bit integer.
 // - category and name strings must have application lifetime (statics or
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h
index 95ea2159..14448e2 100644
--- a/base/trace_event/trace_event.h
+++ b/base/trace_event/trace_event.h
@@ -302,6 +302,23 @@
 
 // Implementation detail: internal macro to create static category and add
 // event if the category is enabled.
+#define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category_group, name, \
+                                                timestamp, flags, ...)       \
+  do {                                                                       \
+    INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                  \
+    if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) {  \
+      trace_event_internal::AddTraceEventWithThreadIdAndTimestamp(           \
+          phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name,     \
+          trace_event_internal::kNoId, trace_event_internal::kNoId,          \
+          TRACE_EVENT_API_CURRENT_THREAD_ID,                                 \
+          base::TimeTicks::FromInternalValue(timestamp),                     \
+          flags | TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP,                       \
+          trace_event_internal::kNoId, ##__VA_ARGS__);                       \
+    }                                                                        \
+  } while (0)
+
+// Implementation detail: internal macro to create static category and add
+// event if the category is enabled.
 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(phase, \
         category_group, name, id, thread_id, timestamp, flags, ...) \
     do { \
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc
index 084c250..533a298 100644
--- a/base/trace_event/trace_event_unittest.cc
+++ b/base/trace_event/trace_event_unittest.cc
@@ -459,6 +459,11 @@
                    "a", 30000,
                    "b", 1415);
 
+    TRACE_COUNTER_WITH_TIMESTAMP1("all", "TRACE_COUNTER_WITH_TIMESTAMP1 call",
+                                  42, 31415);
+    TRACE_COUNTER_WITH_TIMESTAMP2("all", "TRACE_COUNTER_WITH_TIMESTAMP2 call",
+                                  42, "a", 30000, "b", 1415);
+
     TRACE_COUNTER_ID1("all", "TRACE_COUNTER_ID1 call", 0x319009, 31415);
     TRACE_COUNTER_ID2("all", "TRACE_COUNTER_ID2 call", 0x319009,
                       "a", 30000, "b", 1415);
@@ -655,6 +660,39 @@
     EXPECT_EQ(1415, value);
   }
 
+  EXPECT_FIND_("TRACE_COUNTER_WITH_TIMESTAMP1 call");
+  {
+    std::string ph;
+    EXPECT_TRUE((item && item->GetString("ph", &ph)));
+    EXPECT_EQ("C", ph);
+
+    int value;
+    EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
+    EXPECT_EQ(31415, value);
+
+    int ts;
+    EXPECT_TRUE((item && item->GetInteger("ts", &ts)));
+    EXPECT_EQ(42, ts);
+  }
+
+  EXPECT_FIND_("TRACE_COUNTER_WITH_TIMESTAMP2 call");
+  {
+    std::string ph;
+    EXPECT_TRUE((item && item->GetString("ph", &ph)));
+    EXPECT_EQ("C", ph);
+
+    int value;
+    EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
+    EXPECT_EQ(30000, value);
+
+    EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
+    EXPECT_EQ(1415, value);
+
+    int ts;
+    EXPECT_TRUE((item && item->GetInteger("ts", &ts)));
+    EXPECT_EQ(42, ts);
+  }
+
   EXPECT_FIND_("TRACE_COUNTER_ID1 call");
   {
     std::string id;
diff --git a/build/buildflag.h b/build/buildflag.h
new file mode 100644
index 0000000..283f5bc
--- /dev/null
+++ b/build/buildflag.h
@@ -0,0 +1,47 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BUILD_BUILDFLAG_H_
+#define BUILD_BUILDFLAG_H_
+
+// These macros un-mangle the names of the build flags in a way that looks
+// natural, and gives errors if the flag is not defined. Normally in the
+// preprocessor it's easy to make mistakes that interpret "you haven't done
+// the setup to know what the flag is" as "flag is off". Normally you would
+// include the generated header rather than include this file directly.
+//
+// This is for use with generated headers. See build/build_header.gni.
+
+// This dance of two macros does a concatenation of two preprocessor args using
+// ## doubly indirectly because using ## directly prevents macros in that
+// parameter from being expanded.
+#define BUILDFLAG_CAT_INDIRECT(a, b) a ## b
+#define BUILDFLAG_CAT(a, b) BUILDFLAG_CAT_INDIRECT(a, b)
+
+// Accessor for build flags.
+//
+// To test for a value, if the build file specifies:
+//
+//   ENABLE_FOO=true
+//
+// Then you would check at build-time in source code with:
+//
+//   #include "foo_flags.h"  // The header the build file specified.
+//
+//   #if BUILDFLAG(ENABLE_FOO)
+//     ...
+//   #endif
+//
+// There will no #define called ENABLE_FOO so if you accidentally test for
+// whether that is defined, it will always be negative. You can also use
+// the value in expressions:
+//
+//   const char kSpamServerName[] = BUILDFLAG(SPAM_SERVER_NAME);
+//
+// Because the flag is accessed as a preprocessor macro with (), an error
+// will be thrown if the proper header defining the internal flag value has
+// not been included.
+#define BUILDFLAG(flag) (BUILDFLAG_CAT(BUILDFLAG_INTERNAL_, flag)())
+
+#endif  // BUILD_BUILDFLAG_H_
diff --git a/build/buildflag_header.gni b/build/buildflag_header.gni
new file mode 100644
index 0000000..9054d07
--- /dev/null
+++ b/build/buildflag_header.gni
@@ -0,0 +1,138 @@
+# 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.
+
+# Generates a header with preprocessor defines specified by the build file.
+# The GYP version of this (with instructions) is build/buildflag_header.gypi.
+#
+# The flags are converted to function-style defines with mangled names and
+# code uses an accessor macro to access the values. This is to try to
+# minimize bugs where code checks whether something is defined or not, and
+# the proper header isn't included, meaning the answer will always be silently
+# false or might vary across the code base.
+#
+# In the GN template, specify build flags in the template as a list
+# of strings that encode key/value pairs like this:
+#
+#   flags = [ "ENABLE_FOO=1", "ENABLE_BAR=$enable_bar" ]
+#
+# The GN values "true" and "false" will be mapped to 0 and 1 for boolean
+# #if flags to be expressed naturally. This means you can't directly make a
+# define that generates C++ value of true or false for use in code. If you
+# REALLY need this, you can also use the string "(true)" and "(false)" to
+# prevent the rewriting.
+
+# To check the value of the flag in C code:
+#
+#   #include "path/to/here/header_file.h"
+#
+#   #if BUILDFLAG(ENABLE_FOO)
+#   ...
+#   #endif
+#
+#   const char kSpamServerUrl[] = BUILDFLAG(SPAM_SERVER_URL);
+#
+# There will no #define called ENABLE_FOO so if you accidentally test for that
+# in an ifdef it will always be negative.
+#
+#
+# Template parameters
+#
+#   flags [required, list of strings]
+#       Flag values as described above.
+#
+#   header [required, string]
+#       File name for generated header. By default, this will go in the
+#       generated file directory for this target, and you would include it
+#       with:
+#         #include "<path_to_this_BUILD_file>/<header>"
+#
+#   header_dir [optional, string]
+#       Override the default location of the generated header. The string will
+#       be treated as a subdirectory of the root_gen_dir. For example:
+#         header_dir = "foo/bar"
+#       Then you can include the header as:
+#         #include "foo/bar/baz.h"
+#
+#   deps, public_deps, testonly, visibility
+#       Normal meaning.
+#
+#
+# Grit defines
+#
+# If one .grd file uses a flag, just add to the grit target:
+#
+#   defines = [
+#     "enable_doom_melon=$enable_doom_melon",
+#   ]
+#
+# If multiple .grd files use it, you'll want to put the defines in a .gni file
+# so it can be shared. Generally this .gni file should include all grit defines
+# for a given module (for some definition of "module"). Then do:
+#
+#   defines = ui_grit_defines
+#
+# If you forget to do this, the flag will be implicitly false in the .grd file
+# and those resources won't be compiled. You'll know because the resource
+# #define won't be generated and any code that uses it won't compile. If you
+# see a missing IDS_* string, this is probably the reason.
+#
+#
+# Example
+#
+#   buildflag_header("foo_features") {
+#     header = "foo_features.h"
+#
+#     flags = [
+#       # This uses the GN build flag enable_doom_melon as the definition.
+#       "ENABLE_DOOM_MELON=$enable_doom_melon",
+#
+#       # This force-enables the flag.
+#       "ENABLE_SPACE_LASER=true",
+#
+#       # This will expand to the quoted C string when used in source code.
+#       "SPAM_SERVER_URL=\"http://www.example.com/\"",
+#     ]
+#   }
+template("buildflag_header") {
+  action(target_name) {
+    script = "//build/write_buildflag_header.py"
+
+    if (defined(invoker.header_dir)) {
+      header_file = "${invoker.header_dir}/${invoker.header}"
+    } else {
+      # Compute the path from the root to this file.
+      header_file = rebase_path(".", "//") + "/${invoker.header}"
+    }
+
+    outputs = [
+      "$root_gen_dir/$header_file",
+    ]
+
+    # Always write --flags to the file so it's not empty. Empty will confuse GN
+    # into thinking the response file isn't used.
+    response_file_contents = [ "--flags" ]
+    if (defined(invoker.flags)) {
+      response_file_contents += invoker.flags
+    }
+
+    args = [
+      "--output",
+      header_file,  # Not rebased, Python script puts it inside gen-dir.
+      "--rulename",
+      get_label_info(":$target_name", "label_no_toolchain"),
+      "--gen-dir",
+      rebase_path(root_gen_dir, root_out_dir),
+      "--definitions",
+      "{{response_file_name}}",
+    ]
+
+    forward_variables_from(invoker,
+                           [
+                             "deps",
+                             "public_deps",
+                             "testonly",
+                             "visibility",
+                           ])
+  }
+}
diff --git a/build/buildflag_header.gypi b/build/buildflag_header.gypi
new file mode 100644
index 0000000..730ef429
--- /dev/null
+++ b/build/buildflag_header.gypi
@@ -0,0 +1,118 @@
+# 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.
+
+# Generates a header with preprocessor defines specified by the build file.
+#
+# The canonical documentation is in build/buildflag_header.gni. You should
+# write the GN build, get it working, and then transform it into GYP.
+#
+# In every target that uses your generated header you must include a dependency
+# on the GYP target that generates the header (this is implicit in GN).
+# Otherwise, clean builds may not necessarily create the header before the
+# source code is compiled.
+#
+# Assuming your GN code looks like this:
+#
+#   buildflag_header("foo_features") {
+#     header = "foo_features.h"
+#     flags = [
+#       "ENABLE_DOOM_MELON=$enable_doom_melon",
+#       "ENABLE_SPACE_LASER=true",
+#       "SPAM_SERVER_URL=\"http://www.example.com/\"",
+#     ]
+#   }
+#
+# Write a GYP target like this:
+#
+#  {
+#    # GN version: //foo:foo_features
+#    'target_name': 'foo_foo_features',
+#    'includes': [ '../build/buildflag_header.gypi' ],
+#    'variables': {
+#       'buildflag_header_path': 'foo/foo_features.h',
+#       'buildflag_header_flags': [
+#         'ENABLE_DOOM_MELON=<(enable_doom_melon)',
+#         'ENABLE_SPACE_LASER=true',
+#         'SPAM_SERVER_URL="http://www.example.com/"',
+#       ],
+#     },
+#   }
+#
+# Variables
+#
+#   target_name
+#       Base this on the GN label, replacing / and : with _ to make it globally
+#       unique.
+#
+#   buildflag_header_path
+#       This must be the full path to the header from the source root. In GN
+#       you only say "features.h" and it uses the BUILD file's path implicitly.
+#       Use the path to BUILD.gn followed by your header name to produce the
+#       same output file.
+#
+#   buildflag_flags (optional)
+#       List of the same format as GN's "flags". To expand variables, use
+#       "<(foo)" where GN would have used "$foo".
+#
+#   includes
+#       List the relative path to build/buildflag_header.gypi from the .gyp
+#       file including this code, Note: If your code is in a .gypi file in a
+#       different directory, this must be relative to the .gyp including your
+#       file.
+#
+#
+# Grit defines
+#
+# Follow the same advice as in the buildflag_header.gni, except on the grit
+# action use the variable name 'grit_additional_defines' and explicitly add a
+# '-D' in front:
+#
+#   'grit_grd_file': 'foo.grd',
+#   'grit_additional_defines': [
+#     '-D', 'enable_doom_melon=<(enable_doom_melon)',
+#    ],
+#
+# Put shared lists of defines in a .gypi.
+
+{
+  'type': 'none',
+  'hard_dependency': 1,
+
+  'actions': [
+    {
+      'action_name': 'buildflag_header',
+      'variables': {
+        # Default these values to empty if they're not defined.
+        'variables': {
+          'buildflag_flags%': [],
+        },
+
+        # Writes the flags to a response file with a name based on the name of
+        # this target.
+        'response_file_name': '<|(<(_target_name)_buildflag_header.rsp --flags <@(buildflag_flags))',
+
+        'build_header_script': '<(DEPTH)/build/write_buildflag_header.py',
+      },
+
+      'message': 'Generating build header.',
+
+      'inputs': [
+        '<(build_header_script)',
+        '<(response_file_name)',
+      ],
+
+      'outputs': [
+        '<(SHARED_INTERMEDIATE_DIR)/<(buildflag_header_path)',
+      ],
+
+      'action': [
+        'python', '<(build_header_script)',
+        '--output', '<(buildflag_header_path)',
+        '--rulename', '<(_target_name)',
+        '--gen-dir', '<(SHARED_INTERMEDIATE_DIR)',
+        '--definitions', '<(response_file_name)',
+      ],
+    }
+  ],
+}
diff --git a/build/common.gypi b/build/common.gypi
index 9c226a2f..c5d5c85d 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -547,9 +547,6 @@
       # Enable Chrome browser extensions
       'enable_extensions%': 1,
 
-      # Enable Google Now.
-      'enable_google_now%': 1,
-
       # Enable basic printing support and UI.
       'enable_basic_printing%': 1,
 
@@ -819,7 +816,6 @@
 
         ['OS=="android"', {
           'enable_extensions%': 0,
-          'enable_google_now%': 0,
           'cld2_table_size%': 0,
           'enable_themes%': 0,
           'remoting%': 0,
@@ -867,7 +863,6 @@
           'configuration_policy%': 0,
           'disable_ftp_support%': 1,
           'enable_extensions%': 0,
-          'enable_google_now%': 0,
           'cld2_table_size%': 0,
           'enable_basic_printing%': 0,
           'enable_print_preview%': 0,
@@ -1221,7 +1216,6 @@
     'enable_print_preview%': '<(enable_print_preview)',
     'enable_spellcheck%': '<(enable_spellcheck)',
     'use_browser_spellchecker%': '<(use_browser_spellchecker)',
-    'enable_google_now%': '<(enable_google_now)',
     'cld_version%': '<(cld_version)',
     'cld2_table_size%': '<(cld2_table_size)',
     'enable_captive_portal_detection%': '<(enable_captive_portal_detection)',
@@ -2180,9 +2174,6 @@
       ['enable_settings_app==1', {
         'grit_defines': ['-D', 'enable_settings_app'],
       }],
-      ['enable_google_now==1', {
-        'grit_defines': ['-D', 'enable_google_now'],
-      }],
       ['use_concatenated_impulse_responses==1', {
         'grit_defines': ['-D', 'use_concatenated_impulse_responses'],
       }],
@@ -2995,9 +2986,6 @@
       ['enable_background==1', {
         'defines': ['ENABLE_BACKGROUND=1'],
       }],
-      ['enable_google_now==1', {
-        'defines': ['ENABLE_GOOGLE_NOW=1'],
-      }],
       ['enable_basic_printing==1 or enable_print_preview==1', {
         # Convenience define for ENABLE_BASIC_PRINTING || ENABLE_PRINT_PREVIEW.
         'defines': ['ENABLE_PRINTING=1'],
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index 9cc3756..5f85713 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -218,9 +218,6 @@
   if (enable_image_loader_extension) {
     defines += [ "IMAGE_LOADER_EXTENSION=1" ]
   }
-  if (enable_google_now) {
-    defines += [ "ENABLE_GOOGLE_NOW=1" ]
-  }
   if (enable_one_click_signin) {
     defines += [ "ENABLE_ONE_CLICK_SIGNIN" ]
   }
diff --git a/build/config/features.gni b/build/config/features.gni
index 514a6673..1d5f305 100644
--- a/build/config/features.gni
+++ b/build/config/features.gni
@@ -83,8 +83,6 @@
 
   enable_autofill_dialog = !is_ios
 
-  enable_google_now = !is_ios && !is_android
-
   enable_one_click_signin = is_win || is_mac || (is_linux && !is_chromeos)
 
   enable_remoting = !is_ios && !is_chromecast && !is_headless
diff --git a/build/gypi_to_gn.py b/build/gypi_to_gn.py
index a107f94f..6de1a63 100644
--- a/build/gypi_to_gn.py
+++ b/build/gypi_to_gn.py
@@ -96,10 +96,12 @@
   if 'target_conditions' in file_data:
     del file_data['target_conditions']
 
-  # Strip targets in the toplevel, since some files define these and we can't
-  # slurp them in.
+  # Strip targets and includes in the toplevel, since some files define these
+  # and we can't slurp them in.
   if 'targets' in file_data:
     del file_data['targets']
+  if 'includes' in file_data:
+    del file_data['includes']
 
   return file_data
 
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc
index b8afe645..abd4f438 100644
--- a/build/sanitizers/tsan_suppressions.cc
+++ b/build/sanitizers/tsan_suppressions.cc
@@ -258,9 +258,6 @@
 // http://crbug.com/388730
 "race:g_next_user_script_id\n"
 
-// http://crbug.com/389098
-"race:webrtc::voe::TransmitMixer::EnableStereoChannelSwapping\n"
-
 // http://crbug.com/397022
 "deadlock:"
 "base::trace_event::TraceEventTestFixture_ThreadOnceBlocking_Test::TestBody\n"
diff --git a/build/write_buildflag_header.py b/build/write_buildflag_header.py
new file mode 100755
index 0000000..d46cfc8
--- /dev/null
+++ b/build/write_buildflag_header.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+# 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.
+
+# This writes headers for build flags. See buildflag_header.gni for usage of
+# this system as a whole.
+#
+# The parameters are passed in a response file so we don't have to worry
+# about command line lengths. The name of the response file is passed on the
+# command line.
+#
+# The format of the response file is:
+#    [--flags <list of one or more flag values>]
+
+import optparse
+import os
+import shlex
+import sys
+
+
+class Options:
+  def __init__(self, output, rulename, header_guard, flags):
+    self.output = output
+    self.rulename = rulename
+    self.header_guard = header_guard
+    self.flags = flags
+
+
+def GetOptions():
+  parser = optparse.OptionParser()
+  parser.add_option('--output', help="Output header name inside --gen-dir.")
+  parser.add_option('--rulename',
+                    help="Helpful name of build rule for including in the " +
+                         "comment at the top of the file.")
+  parser.add_option('--gen-dir',
+                    help="Path to root of generated file directory tree.")
+  parser.add_option('--definitions',
+                    help="Name of the response file containing the flags.")
+  cmdline_options, cmdline_flags = parser.parse_args()
+
+  # Compute header guard by replacing some chars with _ and upper-casing.
+  header_guard = cmdline_options.output.upper()
+  header_guard = \
+      header_guard.replace('/', '_').replace('\\', '_').replace('.', '_')
+  header_guard += '_'
+
+  # The actual output file is inside the gen dir.
+  output = os.path.join(cmdline_options.gen_dir, cmdline_options.output)
+
+  # Definition file in GYP is newline separated, in GN they are shell formatted.
+  # shlex can parse both of these.
+  with open(cmdline_options.definitions, 'r') as def_file:
+    defs = shlex.split(def_file.read())
+  flags_index = defs.index('--flags')
+
+  # Everything after --flags are flags. true/false are remapped to 1/0,
+  # everything else is passed through.
+  flags = []
+  for flag in defs[flags_index + 1 :]:
+    equals_index = flag.index('=')
+    key = flag[:equals_index]
+    value = flag[equals_index + 1:]
+
+    # Canonicalize and validate the value.
+    if value == 'true':
+      value = '1'
+    elif value == 'false':
+      value = '0'
+    flags.append((key, str(value)))
+
+  return Options(output=output,
+                 rulename=cmdline_options.rulename,
+                 header_guard=header_guard,
+                 flags=flags)
+
+
+def WriteHeader(options):
+  with open(options.output, 'w') as output_file:
+    output_file.write("// Generated by build/write_buildflag_header.py\n")
+    if options.rulename:
+      output_file.write('// From "' + options.rulename + '"\n')
+
+    output_file.write('\n#ifndef %s\n' % options.header_guard)
+    output_file.write('#define %s\n\n' % options.header_guard)
+    output_file.write('#include "build/buildflag.h"\n\n')
+
+    for pair in options.flags:
+      output_file.write('#define BUILDFLAG_INTERNAL_%s() (%s)\n' % pair)
+
+    output_file.write('\n#endif  // %s\n' % options.header_guard)
+
+
+options = GetOptions()
+WriteHeader(options)
diff --git a/chrome/VERSION b/chrome/VERSION
index ac838e90..939f6e6 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=49
 MINOR=0
-BUILD=2575
+BUILD=2576
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkEditActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkEditActivity.java
index 89933b5..7c098a0d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkEditActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkEditActivity.java
@@ -30,6 +30,7 @@
 import org.chromium.chrome.browser.widget.TintedDrawable;
 import org.chromium.components.bookmarks.BookmarkId;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.ui.base.DeviceFormFactor;
 
 /**
  * The activity that enables the user to modify the title, url and parent folder of a bookmark.
@@ -311,9 +312,16 @@
     }
 
     private void openBookmark() {
-        Intent intent = new Intent();
-        intent.putExtra(EnhancedBookmarkActivity.INTENT_VISIT_BOOKMARK_ID, mBookmarkId.toString());
-        setResult(RESULT_OK, intent);
+        // TODO(kkimlabs): Refactor this out to handle the intent in ChromeActivity.
+        if (DeviceFormFactor.isTablet(this)) {
+            EnhancedBookmarkUtils.openBookmark(
+                    mEnhancedBookmarksModel, this, mBookmarkId, LaunchLocation.BOOKMARK_EDITOR);
+        } else {
+            Intent intent = new Intent();
+            intent.putExtra(
+                    EnhancedBookmarkActivity.INTENT_VISIT_BOOKMARK_ID, mBookmarkId.toString());
+            setResult(RESULT_OK, intent);
+        }
         finish();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkManager.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkManager.java
index 12c84cba..e0678dc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkManager.java
@@ -9,7 +9,6 @@
 import android.content.Context;
 import android.preference.PreferenceManager;
 import android.support.v4.widget.DrawerLayout;
-import android.text.TextUtils;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
@@ -18,13 +17,11 @@
 
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.ObserverList;
-import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.UrlConstants;
 import org.chromium.chrome.browser.bookmark.BookmarksBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmark.BookmarksBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.favicon.LargeIconBridge;
-import org.chromium.chrome.browser.ntp.NewTabPageUma;
 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -434,20 +431,8 @@
     @Override
     public void openBookmark(BookmarkId bookmark, int launchLocation) {
         clearSelection();
-        if (mEnhancedBookmarksModel.getBookmarkById(bookmark) != null) {
-            String url = mEnhancedBookmarksModel.getLaunchUrlAndMarkAccessed(mActivity, bookmark);
-            // TODO(jianli): Notify the user about the failure.
-            if (TextUtils.isEmpty(url)) return;
-
-            NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_BOOKMARK);
-            if (url.startsWith("file:")) {
-                RecordHistogram.recordEnumeratedHistogram("OfflinePages.LaunchLocation",
-                        launchLocation, LaunchLocation.COUNT);
-            } else {
-                RecordHistogram.recordEnumeratedHistogram("Stars.LaunchLocation", launchLocation,
-                        LaunchLocation.COUNT);
-            }
-            EnhancedBookmarkUtils.openBookmark(mActivity, url);
+        if (EnhancedBookmarkUtils.openBookmark(
+                    mEnhancedBookmarksModel, mActivity, bookmark, launchLocation)) {
             EnhancedBookmarkUtils.finishActivityOnPhone(mActivity);
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java
index 938d8380..62873dfa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkUtils.java
@@ -12,8 +12,10 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.provider.Browser;
+import android.text.TextUtils;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeBrowserProviderClient;
@@ -24,6 +26,7 @@
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.enhancedbookmarks.EnhancedBookmarksModel.AddBookmarkCallback;
 import org.chromium.chrome.browser.favicon.FaviconHelper;
+import org.chromium.chrome.browser.ntp.NewTabPageUma;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 import org.chromium.chrome.browser.offlinepages.OfflinePageFreeUpSpaceCallback;
 import org.chromium.chrome.browser.offlinepages.OfflinePageFreeUpSpaceDialog;
@@ -263,7 +266,7 @@
             return false;
         }
         if (DeviceFormFactor.isTablet(activity)) {
-            openBookmark(activity, UrlConstants.BOOKMARKS_URL);
+            openUrl(activity, UrlConstants.BOOKMARKS_URL);
         } else {
             activity.startActivity(new Intent(activity, EnhancedBookmarkActivity.class));
         }
@@ -319,7 +322,37 @@
         return BookmarkId.getBookmarkIdFromString(bundle.getString(BOOKMARK_SAVE_NAME));
     }
 
-    public static void openBookmark(Activity activity, String url) {
+    /**
+     * Opens a bookmark depending on connection status and reports UMA.
+     * @param model Enhanced bookmarks model to manage the bookmark.
+     * @param activity Activity requesting to open the bookmark.
+     * @param bookmarkId ID of the bookmark to be opened.
+     * @param launchLocation Location from which the bookmark is being opened.
+     * @return Whether the bookmark was successfully opened.
+     */
+    public static boolean openBookmark(EnhancedBookmarksModel model, Activity activity,
+            BookmarkId bookmarkId, int launchLocation) {
+        if (model.getBookmarkById(bookmarkId) == null) return false;
+
+        String url = model.getLaunchUrlAndMarkAccessed(activity, bookmarkId);
+
+        // TODO(jianli): Notify the user about the failure.
+        if (TextUtils.isEmpty(url)) return false;
+
+        NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_BOOKMARK);
+        if (url.startsWith("file:")) {
+            RecordHistogram.recordEnumeratedHistogram(
+                    "OfflinePages.LaunchLocation", launchLocation, LaunchLocation.COUNT);
+        } else {
+            RecordHistogram.recordEnumeratedHistogram(
+                    "Stars.LaunchLocation", launchLocation, LaunchLocation.COUNT);
+        }
+
+        openUrl(activity, url);
+        return true;
+    }
+
+    private static void openUrl(Activity activity, String url) {
         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
         intent.setClassName(activity.getApplicationContext().getPackageName(),
                 ChromeLauncherActivity.class.getName());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
index 41ad51d..2c10a2fd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -110,6 +110,9 @@
 
     private boolean mIsLoaded;
 
+    // Whether the NTP has loaded once and is in the foreground.
+    private boolean mIsVisible;
+
     // Whether destroy() has been called.
     private boolean mIsDestroyed;
 
@@ -407,6 +410,7 @@
             RecordHistogram.recordTimesHistogram(
                     "Tab.NewTabOnload", loadTimeMs, TimeUnit.MILLISECONDS);
             mIsLoaded = true;
+            mIsVisible = true;
             StartupMetrics.getInstance().recordOpenedNTP();
 
             if (mIsDestroyed) return;
@@ -451,6 +455,13 @@
             public void onShown(Tab tab) {
                 // Showing the NTP is only meaningful when the page has been loaded already.
                 if (mIsLoaded) recordNTPShown();
+                mIsVisible = true;
+            }
+
+            @Override
+            public void onHidden(Tab tab) {
+                recordNTPInteractionTime();
+                mIsVisible = false;
             }
         };
         mTab.addObserver(mTabObserver);
@@ -574,6 +585,11 @@
         RecordUserAction.record("MobileNTPShown");
     }
 
+    private void recordNTPInteractionTime() {
+        RecordHistogram.recordMediumTimesHistogram(
+                "NewTabPage.TimeSpent", System.nanoTime() - mLastShownTimeNs, TimeUnit.NANOSECONDS);
+    }
+
     /**
      * @return Whether the NTP has finished loaded.
      */
@@ -595,6 +611,7 @@
     public void destroy() {
         assert !mIsDestroyed;
         assert getView().getParent() == null : "Destroy called before removed from window";
+        if (mIsVisible) recordNTPInteractionTime();
         if (mFaviconHelper != null) {
             mFaviconHelper.destroy();
             mFaviconHelper = null;
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 44416e7..d528833 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -6,6 +6,7 @@
 import("//build/config/crypto.gni")
 import("//build/config/features.gni")
 import("//build/config/ui.gni")
+import("//chrome/common/features.gni")
 import("//media/media_options.gni")
 import("//third_party/protobuf/proto_library.gni")
 
@@ -957,6 +958,7 @@
 # (generate_browser_resources action)
 grit("resources") {
   source = "browser_resources.grd"
+  defines = chrome_grit_defines
   output_dir = "$root_gen_dir/chrome"
   outputs = [
     "grit/browser_resources.h",
diff --git a/chrome/browser/apps/drive/drive_service_bridge.cc b/chrome/browser/apps/drive/drive_service_bridge.cc
index f3facb04..916bcd5e 100644
--- a/chrome/browser/apps/drive/drive_service_bridge.cc
+++ b/chrome/browser/apps/drive/drive_service_bridge.cc
@@ -83,6 +83,7 @@
       drive_task_runner.get(),
       GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction),
       GURL(google_apis::DriveApiUrlGenerator::kBaseDownloadUrlForProduction),
+      GURL(google_apis::DriveApiUrlGenerator::kBaseThumbnailUrlForProduction),
       std::string() /* custom_user_agent */));
   SigninManagerBase* signin_manager =
       SigninManagerFactory::GetForProfile(profile_);
diff --git a/chrome/browser/autofill/autofill_server_browsertest.cc b/chrome/browser/autofill/autofill_server_browsertest.cc
index 18498d182..b5b28165 100644
--- a/chrome/browser/autofill/autofill_server_browsertest.cc
+++ b/chrome/browser/autofill/autofill_server_browsertest.cc
@@ -149,14 +149,14 @@
       "  };"
       "</script>";
   const char kQueryRequest[] =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+      "<?xml version=\"1.0\"?>\n"
       "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
       "<form signature=\"15916856893790176210\">"
       "<field signature=\"2594484045\" name=\"one\" type=\"text\"/>"
       "<field signature=\"2750915947\" name=\"two\" type=\"text\"/>"
       "<field signature=\"3494787134\" name=\"three\" type=\"text\"/>"
       "<field signature=\"1236501728\" name=\"four\" type=\"text\"/></form>"
-      "</autofillquery>";
+      "</autofillquery>\n";
   WindowedNetworkObserver query_network_observer(Compress(kQueryRequest));
   ui_test_utils::NavigateToURL(
       browser(), GURL(std::string(kDataURIPrefix) + kFormHtml));
@@ -166,7 +166,7 @@
   // triggered by user gestures are ignored. Expect an upload request upon form
   // submission, with form fields matching those from the query request.
   const char kUploadRequest[] =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+      "<?xml version=\"1.0\"?>\n"
       "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
       " formsignature=\"15916856893790176210\""
       " autofillused=\"false\""
@@ -180,7 +180,7 @@
       " autofilltype=\"2\"/>"
       "<field signature=\"1236501728\" name=\"four\" type=\"text\""
       " autocomplete=\"off\" autofilltype=\"2\"/>"
-      "</autofillupload>";
+      "</autofillupload>\n";
 
   WindowedNetworkObserver upload_network_observer(Compress(kUploadRequest));
   content::WebContents* web_contents =
@@ -204,13 +204,13 @@
       "  <input type='submit'>"
       "</form>";
   const char kQueryRequest[] =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+      "<?xml version=\"1.0\"?>\n"
       "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
       "<form signature=\"8900697631820480876\">"
       "<field signature=\"2594484045\" name=\"one\" type=\"text\"/>"
       "<field signature=\"2750915947\" name=\"two\" type=\"text\"/>"
       "<field signature=\"116843943\" name=\"three\" type=\"password\"/>"
-      "</form></autofillquery>";
+      "</form></autofillquery>\n";
   WindowedNetworkObserver query_network_observer(Compress(kQueryRequest));
   ui_test_utils::NavigateToURL(
       browser(), GURL(std::string(kDataURIPrefix) + kFormHtml));
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index c69f48f9..9a1c03b8 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -388,11 +388,13 @@
 
   wake_on_wifi_manager_.reset(new WakeOnWifiManager());
 
-  arc_bridge_service_.reset(new arc::ArcBridgeService(
-      content::BrowserThread::GetMessageLoopProxyForThread(
-          content::BrowserThread::IO),
-      content::BrowserThread::GetMessageLoopProxyForThread(
-          content::BrowserThread::FILE)));
+  arc_bridge_service_ =
+      arc::ArcBridgeService::Create(
+          content::BrowserThread::GetMessageLoopProxyForThread(
+              content::BrowserThread::IO),
+          content::BrowserThread::GetMessageLoopProxyForThread(
+              content::BrowserThread::FILE))
+          .Pass();
   arc_bridge_service_->DetectAvailability();
 
   ChromeBrowserMainPartsLinux::PreMainMessageLoopRun();
diff --git a/chrome/browser/chromeos/drive/drive_integration_service.cc b/chrome/browser/chromeos/drive/drive_integration_service.cc
index a9951e3..37c9f84 100644
--- a/chrome/browser/chromeos/drive/drive_integration_service.cc
+++ b/chrome/browser/chromeos/drive/drive_integration_service.cc
@@ -234,11 +234,11 @@
     drive_service_.reset(test_drive_service);
   } else {
     drive_service_.reset(new DriveAPIService(
-        oauth_service,
-        g_browser_process->system_request_context(),
+        oauth_service, g_browser_process->system_request_context(),
         blocking_task_runner_.get(),
         GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction),
         GURL(google_apis::DriveApiUrlGenerator::kBaseDownloadUrlForProduction),
+        GURL(google_apis::DriveApiUrlGenerator::kBaseThumbnailUrlForProduction),
         GetDriveUserAgent()));
   }
   scheduler_.reset(new JobScheduler(
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
index caec650..7f2f1d70 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -96,7 +96,9 @@
     DriveApiUrlGenerator url_generator(
         (GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction)),
         (GURL(
-            google_apis::DriveApiUrlGenerator::kBaseDownloadUrlForProduction)));
+            google_apis::DriveApiUrlGenerator::kBaseDownloadUrlForProduction)),
+        (GURL(google_apis::DriveApiUrlGenerator::
+                  kBaseThumbnailUrlForProduction)));
     properties->thumbnail_url.reset(new std::string(
         url_generator.GetThumbnailUrl(entry_proto.resource_id(),
                                       500 /* width */, 500 /* height */,
@@ -429,13 +431,27 @@
     }
 
     ProvidedFileSystemInterface::MetadataFieldMask field_mask =
-        ProvidedFileSystemInterface::METADATA_FIELD_DEFAULT;
-    // TODO(mtomasz): Add other fields. All of them should be requested on
-    // demand. crbug.com/413161.
+        ProvidedFileSystemInterface::METADATA_FIELD_NONE;
+    if (names_.find(api::file_manager_private::ENTRY_PROPERTY_NAME_SIZE) !=
+        names_.end()) {
+      field_mask |= ProvidedFileSystemInterface::METADATA_FIELD_SIZE;
+    }
+    if (names_.find(
+            api::file_manager_private::ENTRY_PROPERTY_NAME_MODIFICATIONTIME) !=
+        names_.end()) {
+      field_mask |=
+          ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME;
+    }
+    if (names_.find(
+            api::file_manager_private::ENTRY_PROPERTY_NAME_CONTENTMIMETYPE) !=
+        names_.end()) {
+      field_mask |= ProvidedFileSystemInterface::METADATA_FIELD_MIME_TYPE;
+    }
     if (names_.find(
             api::file_manager_private::ENTRY_PROPERTY_NAME_THUMBNAILURL) !=
-        names_.end())
+        names_.end()) {
       field_mask |= ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL;
+    }
 
     parser.file_system()->GetMetadata(
         parser.file_path(), field_mask,
@@ -453,15 +469,31 @@
       return;
     }
 
-    properties_->size.reset(new double(metadata->size));
-    properties_->modification_time.reset(
-        new double(metadata->modification_time.ToJsTime()));
+    if (names_.find(api::file_manager_private::ENTRY_PROPERTY_NAME_SIZE) !=
+        names_.end()) {
+      properties_->size.reset(new double(*metadata->size.get()));
+    }
 
-    if (!metadata->thumbnail.empty())
-      properties_->thumbnail_url.reset(new std::string(metadata->thumbnail));
-    if (!metadata->mime_type.empty()) {
+    if (names_.find(
+            api::file_manager_private::ENTRY_PROPERTY_NAME_MODIFICATIONTIME) !=
+        names_.end()) {
+      properties_->modification_time.reset(
+          new double(metadata->modification_time->ToJsTime()));
+    }
+
+    if (names_.find(
+            api::file_manager_private::ENTRY_PROPERTY_NAME_CONTENTMIMETYPE) !=
+            names_.end() &&
+        metadata->mime_type.get()) {
       properties_->content_mime_type.reset(
-          new std::string(metadata->mime_type));
+          new std::string(*metadata->mime_type));
+    }
+
+    if (names_.find(
+            api::file_manager_private::ENTRY_PROPERTY_NAME_THUMBNAILURL) !=
+            names_.end() &&
+        metadata->thumbnail.get()) {
+      properties_->thumbnail_url.reset(new std::string(*metadata->thumbnail));
     }
 
     CompleteGetEntryProperties(base::File::FILE_OK);
@@ -1068,7 +1100,9 @@
 
   DriveApiUrlGenerator url_generator(
       (GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction)),
-      (GURL(google_apis::DriveApiUrlGenerator::kBaseDownloadUrlForProduction)));
+      (GURL(google_apis::DriveApiUrlGenerator::kBaseDownloadUrlForProduction)),
+      (GURL(
+          google_apis::DriveApiUrlGenerator::kBaseThumbnailUrlForProduction)));
   download_url_ = url_generator.GenerateDownloadFileUrl(entry->resource_id());
 
   ProfileOAuth2TokenService* oauth2_token_service =
diff --git a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
index ad0e0691..6990183 100644
--- a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
+++ b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
@@ -561,9 +561,11 @@
 class MultiProfileDriveFileSystemExtensionApiTest :
     public FileSystemExtensionApiTestBase {
  public:
-  MultiProfileDriveFileSystemExtensionApiTest() : second_profile(NULL) {}
+  MultiProfileDriveFileSystemExtensionApiTest() : second_profile_(NULL) {}
 
   void SetUpOnMainThread() override {
+    ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
+
     base::FilePath user_data_directory;
     PathService::Get(chrome::DIR_USER_DATA, &user_data_directory);
     user_manager::UserManager::Get()->UserLoggedIn(
@@ -574,7 +576,7 @@
         user_data_directory.Append(
             chromeos::ProfileHelper::GetUserProfileDir(
                 kSecondProfileHash).BaseName());
-    second_profile =
+    second_profile_ =
         g_browser_process->profile_manager()->GetProfile(profile_dir);
 
     FileSystemExtensionApiTestBase::SetUpOnMainThread();
@@ -593,7 +595,7 @@
 
   void AddTestMountPoint() override {
     test_util::WaitUntilDriveMountPointIsAdded(browser()->profile());
-    test_util::WaitUntilDriveMountPointIsAdded(second_profile);
+    test_util::WaitUntilDriveMountPointIsAdded(second_profile_);
   }
 
  protected:
@@ -601,7 +603,8 @@
   drive::DriveIntegrationService* CreateDriveIntegrationService(
       Profile* profile) {
     base::FilePath cache_dir;
-    base::CreateNewTempDirectory(base::FilePath::StringType(), &cache_dir);
+    base::CreateTemporaryDirInDir(tmp_dir_.path(), base::FilePath::StringType(),
+                                  &cache_dir);
 
     drive::FakeDriveService* const fake_drive_service =
         new drive::FakeDriveService;
@@ -619,7 +622,7 @@
             drive::util::GetDriveServiceByProfile(browser()->profile()));
     drive::FakeDriveService* const sub_service =
         static_cast<drive::FakeDriveService*>(
-            drive::util::GetDriveServiceByProfile(second_profile));
+            drive::util::GetDriveServiceByProfile(second_profile_));
 
     google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
     scoped_ptr<google_apis::FileResource> entry;
@@ -645,11 +648,12 @@
     return (error == google_apis::HTTP_CREATED);
   }
 
+  base::ScopedTempDir tmp_dir_;
   DriveIntegrationServiceFactory::FactoryCallback
       create_drive_integration_service_;
   scoped_ptr<DriveIntegrationServiceFactory::ScopedFactoryForTest>
       service_factory_for_test_;
-  Profile* second_profile;
+  Profile* second_profile_;
   std::map<std::string, std::string> resource_ids_;
 };
 
diff --git a/chrome/browser/chromeos/file_manager/filesystem_api_util.cc b/chrome/browser/chromeos/file_manager/filesystem_api_util.cc
index b97071f3..231fbd16 100644
--- a/chrome/browser/chromeos/file_manager/filesystem_api_util.cc
+++ b/chrome/browser/chromeos/file_manager/filesystem_api_util.cc
@@ -51,11 +51,11 @@
     base::File::Error result) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  if (result != base::File::FILE_OK || metadata->mime_type.empty()) {
+  if (result != base::File::FILE_OK || !metadata->mime_type.get()) {
     callback.Run(false, std::string());
     return;
   }
-  callback.Run(true, metadata->mime_type);
+  callback.Run(true, *metadata->mime_type);
 }
 
 // Helper function to converts a callback that takes boolean value to that takes
@@ -176,7 +176,7 @@
     parser.file_system()->GetMetadata(
         parser.file_path(),
         chromeos::file_system_provider::ProvidedFileSystemInterface::
-            METADATA_FIELD_DEFAULT,
+            METADATA_FIELD_MIME_TYPE,
         base::Bind(&GetMimeTypeAfterGetMetadataForProvidedFileSystem,
                    callback));
     return;
diff --git a/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc
index fb3fce5..03fb9af 100644
--- a/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc
+++ b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc
@@ -60,11 +60,11 @@
   DCHECK(entries_.find(entry_path) == entries_.end());
   scoped_ptr<EntryMetadata> metadata(new EntryMetadata);
 
-  metadata->is_directory = is_directory;
-  metadata->name = name;
-  metadata->size = size;
-  metadata->modification_time = modification_time;
-  metadata->mime_type = mime_type;
+  metadata->is_directory.reset(new bool(is_directory));
+  metadata->name.reset(new std::string(name));
+  metadata->size.reset(new int64(size));
+  metadata->modification_time.reset(new base::Time(modification_time));
+  metadata->mime_type.reset(new std::string(mime_type));
 
   entries_[entry_path] =
       make_linked_ptr(new FakeEntry(metadata.Pass(), contents));
@@ -98,12 +98,28 @@
   }
 
   scoped_ptr<EntryMetadata> metadata(new EntryMetadata);
-  metadata->is_directory = entry_it->second->metadata->is_directory;
-  metadata->name = entry_it->second->metadata->name;
-  metadata->size = entry_it->second->metadata->size;
-  metadata->modification_time = entry_it->second->metadata->modification_time;
-  metadata->mime_type = entry_it->second->metadata->mime_type;
-  metadata->thumbnail = entry_it->second->metadata->thumbnail;
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_IS_DIRECTORY) {
+    metadata->is_directory.reset(
+        new bool(*entry_it->second->metadata->is_directory));
+  }
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_NAME)
+    metadata->name.reset(new std::string(*entry_it->second->metadata->name));
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_SIZE)
+    metadata->size.reset(new int64(*entry_it->second->metadata->size));
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME) {
+    metadata->modification_time.reset(
+        new base::Time(*entry_it->second->metadata->modification_time));
+  }
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_MIME_TYPE &&
+      entry_it->second->metadata->mime_type.get()) {
+    metadata->mime_type.reset(
+        new std::string(*entry_it->second->metadata->mime_type));
+  }
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL &&
+      entry_it->second->metadata->thumbnail.get()) {
+    metadata->thumbnail.reset(
+        new std::string(*entry_it->second->metadata->thumbnail));
+  }
 
   return PostAbortableTask(
       base::Bind(callback, base::Passed(&metadata), base::File::FILE_OK));
@@ -136,9 +152,9 @@
     if (file_path == directory_path || directory_path.IsParent(file_path)) {
       const EntryMetadata* const metadata = it->second->metadata.get();
       entry_list.push_back(storage::DirectoryEntry(
-          metadata->name, metadata->is_directory
-                              ? storage::DirectoryEntry::DIRECTORY
-                              : storage::DirectoryEntry::FILE));
+          *metadata->name, *metadata->is_directory
+                               ? storage::DirectoryEntry::DIRECTORY
+                               : storage::DirectoryEntry::FILE));
     }
   }
 
@@ -209,7 +225,7 @@
   int current_length = length;
 
   // Reading behind EOF is fine, it will just return 0 bytes.
-  if (current_offset >= entry_it->second->metadata->size || !current_length) {
+  if (current_offset >= *entry_it->second->metadata->size || !current_length) {
     return PostAbortableTask(base::Bind(callback,
                                         0 /* chunk_length */,
                                         false /* has_more */,
@@ -218,10 +234,10 @@
 
   const FakeEntry* const entry = entry_it->second.get();
   std::vector<int> task_ids;
-  while (current_offset < entry->metadata->size && current_length) {
+  while (current_offset < *entry->metadata->size && current_length) {
     buffer->data()[current_offset - offset] = entry->contents[current_offset];
     const bool has_more =
-        (current_offset + 1 < entry->metadata->size) && (current_length - 1);
+        (current_offset + 1 < *entry->metadata->size) && (current_length - 1);
     const int task_id =
         tracker_.PostTask(base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
                           base::Bind(callback, 1 /* chunk_length */, has_more,
@@ -308,15 +324,15 @@
   }
 
   FakeEntry* const entry = entry_it->second.get();
-  if (offset > entry->metadata->size) {
+  if (offset > *entry->metadata->size) {
     return PostAbortableTask(
         base::Bind(callback, base::File::FILE_ERROR_INVALID_OPERATION));
   }
 
   // Allocate the string size in advance.
-  if (offset + length > entry->metadata->size) {
-    entry->metadata->size = offset + length;
-    entry->contents.resize(entry->metadata->size);
+  if (offset + length > *entry->metadata->size) {
+    *entry->metadata->size = offset + length;
+    entry->contents.resize(*entry->metadata->size);
   }
 
   entry->contents.replace(offset, length, buffer->data(), length);
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc
index ce5a231..9af8931 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc
@@ -110,9 +110,9 @@
 
     abort_callback_ = file_system_->GetMetadata(
         file_path_,
-        ProvidedFileSystemInterface::METADATA_FIELD_DEFAULT,
-        base::Bind(&OperationRunner::OnGetMetadataCompletedOnUIThread,
-                   this,
+        ProvidedFileSystemInterface::METADATA_FIELD_SIZE |
+            ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME,
+        base::Bind(&OperationRunner::OnGetMetadataCompletedOnUIThread, this,
                    callback));
   }
 
@@ -286,7 +286,7 @@
   // may be changed without affecting the modification time.
   DCHECK(metadata.get());
   if (!expected_modification_time_.is_null() &&
-      metadata->modification_time != expected_modification_time_) {
+      *metadata->modification_time != expected_modification_time_) {
     state_ = FAILED;
     error_callback.Run(net::ERR_UPLOAD_FILE_CHANGED);
     return;
@@ -466,13 +466,13 @@
   // may be changed without affecting the modification time.
   DCHECK(metadata.get());
   if (!expected_modification_time_.is_null() &&
-      metadata->modification_time != expected_modification_time_) {
+      *metadata->modification_time != expected_modification_time_) {
     callback.Run(net::ERR_UPLOAD_FILE_CHANGED);
     return;
   }
 
   DCHECK_EQ(base::File::FILE_OK, result);
-  callback.Run(metadata->size);
+  callback.Run(*metadata->size);
 }
 
 }  // namespace file_system_provider
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader_unittest.cc b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader_unittest.cc
index 2213239..d9db120d 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader_unittest.cc
@@ -125,23 +125,22 @@
   EventLogger logger;
 
   const int64 initial_offset = 0;
-  FileStreamReader reader(
-      NULL, file_url_, initial_offset, fake_file_->metadata->modification_time);
+  FileStreamReader reader(NULL, file_url_, initial_offset,
+                          *fake_file_->metadata->modification_time);
   scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(
-      base::CheckedNumeric<size_t>(fake_file_->metadata->size).ValueOrDie()));
+      base::CheckedNumeric<size_t>(*fake_file_->metadata->size).ValueOrDie()));
 
   const int result =
-      reader.Read(io_buffer.get(),
-                  fake_file_->metadata->size,
+      reader.Read(io_buffer.get(), *fake_file_->metadata->size,
                   base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
   EXPECT_EQ(net::ERR_IO_PENDING, result);
   base::RunLoop().RunUntilIdle();
 
   ASSERT_EQ(1u, logger.results().size());
   EXPECT_LT(0, logger.results()[0]);
-  EXPECT_EQ(fake_file_->metadata->size, logger.results()[0]);
+  EXPECT_EQ(*fake_file_->metadata->size, logger.results()[0]);
 
-  std::string buffer_as_string(io_buffer->data(), fake_file_->metadata->size);
+  std::string buffer_as_string(io_buffer->data(), *fake_file_->metadata->size);
   EXPECT_EQ(fake_file_->contents, buffer_as_string);
 }
 
@@ -149,16 +148,13 @@
   EventLogger logger;
 
   const int64 initial_offset = 0;
-  FileStreamReader reader(NULL,
-                          wrong_file_url_,
-                          initial_offset,
-                          fake_file_->metadata->modification_time);
+  FileStreamReader reader(NULL, wrong_file_url_, initial_offset,
+                          *fake_file_->metadata->modification_time);
   scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(
-      base::CheckedNumeric<size_t>(fake_file_->metadata->size).ValueOrDie()));
+      base::CheckedNumeric<size_t>(*fake_file_->metadata->size).ValueOrDie()));
 
   const int result =
-      reader.Read(io_buffer.get(),
-                  fake_file_->metadata->size,
+      reader.Read(io_buffer.get(), *fake_file_->metadata->size,
                   base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
   EXPECT_EQ(net::ERR_IO_PENDING, result);
   base::RunLoop().RunUntilIdle();
@@ -171,10 +167,10 @@
   EventLogger logger;
 
   const int64 initial_offset = 0;
-  FileStreamReader reader(
-      NULL, file_url_, initial_offset, fake_file_->metadata->modification_time);
+  FileStreamReader reader(NULL, file_url_, initial_offset,
+                          *fake_file_->metadata->modification_time);
 
-  for (int64 offset = 0; offset < fake_file_->metadata->size; ++offset) {
+  for (int64 offset = 0; offset < *fake_file_->metadata->size; ++offset) {
     scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(1));
     const int result =
         reader.Read(io_buffer.get(),
@@ -193,12 +189,12 @@
 
   // Trim first 3 and last 3 characters.
   const int64 initial_offset = 3;
-  const int length = fake_file_->metadata->size - initial_offset - 3;
-  ASSERT_GT(fake_file_->metadata->size, initial_offset);
+  const int length = *fake_file_->metadata->size - initial_offset - 3;
+  ASSERT_GT(*fake_file_->metadata->size, initial_offset);
   ASSERT_LT(0, length);
 
-  FileStreamReader reader(
-      NULL, file_url_, initial_offset, fake_file_->metadata->modification_time);
+  FileStreamReader reader(NULL, file_url_, initial_offset,
+                          *fake_file_->metadata->modification_time);
   scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(length));
 
   const int result =
@@ -222,10 +218,10 @@
 
   // Request reading 1KB more than available.
   const int64 initial_offset = 0;
-  const int length = fake_file_->metadata->size + 1024;
+  const int length = *fake_file_->metadata->size + 1024;
 
-  FileStreamReader reader(
-      NULL, file_url_, initial_offset, fake_file_->metadata->modification_time);
+  FileStreamReader reader(NULL, file_url_, initial_offset,
+                          *fake_file_->metadata->modification_time);
   scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(length));
 
   const int result =
@@ -237,9 +233,9 @@
 
   ASSERT_EQ(1u, logger.results().size());
   EXPECT_LT(0, logger.results()[0]);
-  EXPECT_EQ(fake_file_->metadata->size, logger.results()[0]);
+  EXPECT_EQ(*fake_file_->metadata->size, logger.results()[0]);
 
-  std::string buffer_as_string(io_buffer->data(), fake_file_->metadata->size);
+  std::string buffer_as_string(io_buffer->data(), *fake_file_->metadata->size);
   EXPECT_EQ(fake_file_->contents, buffer_as_string);
 }
 
@@ -250,10 +246,9 @@
   FileStreamReader reader(NULL, file_url_, initial_offset, base::Time::Max());
 
   scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(
-      base::CheckedNumeric<size_t>(fake_file_->metadata->size).ValueOrDie()));
+      base::CheckedNumeric<size_t>(*fake_file_->metadata->size).ValueOrDie()));
   const int result =
-      reader.Read(io_buffer.get(),
-                  fake_file_->metadata->size,
+      reader.Read(io_buffer.get(), *fake_file_->metadata->size,
                   base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
 
   EXPECT_EQ(net::ERR_IO_PENDING, result);
@@ -270,19 +265,18 @@
   FileStreamReader reader(NULL, file_url_, initial_offset, base::Time());
 
   scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(
-      base::CheckedNumeric<size_t>(fake_file_->metadata->size).ValueOrDie()));
+      base::CheckedNumeric<size_t>(*fake_file_->metadata->size).ValueOrDie()));
   const int result =
-      reader.Read(io_buffer.get(),
-                  fake_file_->metadata->size,
+      reader.Read(io_buffer.get(), *fake_file_->metadata->size,
                   base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
 
   EXPECT_EQ(net::ERR_IO_PENDING, result);
   base::RunLoop().RunUntilIdle();
 
   ASSERT_EQ(1u, logger.results().size());
-  EXPECT_EQ(fake_file_->metadata->size, logger.results()[0]);
+  EXPECT_EQ(*fake_file_->metadata->size, logger.results()[0]);
 
-  std::string buffer_as_string(io_buffer->data(), fake_file_->metadata->size);
+  std::string buffer_as_string(io_buffer->data(), *fake_file_->metadata->size);
   EXPECT_EQ(fake_file_->contents, buffer_as_string);
 }
 
@@ -290,8 +284,8 @@
   EventLogger logger;
 
   const int64 initial_offset = 0;
-  FileStreamReader reader(
-      NULL, file_url_, initial_offset, fake_file_->metadata->modification_time);
+  FileStreamReader reader(NULL, file_url_, initial_offset,
+                          *fake_file_->metadata->modification_time);
 
   const int result = reader.GetLength(
       base::Bind(&EventLogger::OnGetLength, logger.GetWeakPtr()));
@@ -300,17 +294,15 @@
 
   ASSERT_EQ(1u, logger.results().size());
   EXPECT_LT(0, logger.results()[0]);
-  EXPECT_EQ(fake_file_->metadata->size, logger.results()[0]);
+  EXPECT_EQ(*fake_file_->metadata->size, logger.results()[0]);
 }
 
 TEST_F(FileSystemProviderFileStreamReader, GetLength_WrongFile) {
   EventLogger logger;
 
   const int64 initial_offset = 0;
-  FileStreamReader reader(NULL,
-                          wrong_file_url_,
-                          initial_offset,
-                          fake_file_->metadata->modification_time);
+  FileStreamReader reader(NULL, wrong_file_url_, initial_offset,
+                          *fake_file_->metadata->modification_time);
 
   const int result = reader.GetLength(
       base::Bind(&EventLogger::OnGetLength, logger.GetWeakPtr()));
@@ -350,7 +342,7 @@
 
   ASSERT_EQ(1u, logger.results().size());
   EXPECT_LT(0, logger.results()[0]);
-  EXPECT_EQ(fake_file_->metadata->size, logger.results()[0]);
+  EXPECT_EQ(*fake_file_->metadata->size, logger.results()[0]);
 }
 
 }  // namespace file_system_provider
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer_unittest.cc b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer_unittest.cc
index 10df3e7..c05b2526 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer_unittest.cc
@@ -214,7 +214,7 @@
   ASSERT_TRUE(entry);
 
   const std::string original_contents = entry->contents;
-  const int64 initial_offset = entry->metadata->size;
+  const int64 initial_offset = *entry->metadata->size;
   ASSERT_LT(0, initial_offset);
 
   FileStreamWriter writer(file_url_, initial_offset);
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc b/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc
index f1ad803f..a79799a 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc
@@ -26,7 +26,7 @@
 void GetFileInfoOnUIThread(
     scoped_ptr<storage::FileSystemOperationContext> context,
     const storage::FileSystemURL& url,
-    int /* fields */,
+    int fields,
     const ProvidedFileSystemInterface::GetMetadataCallback& callback) {
   util::FileSystemURLParser parser(url);
   if (!parser.Parse()) {
@@ -35,17 +35,21 @@
     return;
   }
 
-  // TODO(mtomasz): Pass fields to FSP extensions so only requested fields are
-  // returned.
-  parser.file_system()->GetMetadata(
-      parser.file_path(),
-      ProvidedFileSystemInterface::METADATA_FIELD_DEFAULT,
-      callback);
+  int fsp_fields = 0;
+  if (fields & storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY)
+    fsp_fields |= ProvidedFileSystemInterface::METADATA_FIELD_IS_DIRECTORY;
+  if (fields & storage::FileSystemOperation::GET_METADATA_FIELD_SIZE)
+    fsp_fields |= ProvidedFileSystemInterface::METADATA_FIELD_SIZE;
+  if (fields & storage::FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED)
+    fsp_fields |= ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME;
+
+  parser.file_system()->GetMetadata(parser.file_path(), fsp_fields, callback);
 }
 
 // Routes the response of GetFileInfo back to the IO thread with a type
 // conversion.
-void OnGetFileInfo(const storage::AsyncFileUtil::GetFileInfoCallback& callback,
+void OnGetFileInfo(int fields,
+                   const storage::AsyncFileUtil::GetFileInfoCallback& callback,
                    scoped_ptr<EntryMetadata> metadata,
                    base::File::Error result) {
   if (result != base::File::FILE_OK) {
@@ -58,14 +62,20 @@
   DCHECK(metadata.get());
   base::File::Info file_info;
 
-  // TODO(mtomasz): Add support for last modified time and creation time.
-  // See: crbug.com/388540.
-  file_info.size = metadata->size;
-  file_info.is_directory = metadata->is_directory;
+  if (fields & storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY)
+    file_info.is_directory = *metadata->is_directory;
+  if (fields & storage::FileSystemOperation::GET_METADATA_FIELD_SIZE)
+    file_info.size = *metadata->size;
+
+  if (fields & storage::FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED) {
+    file_info.last_modified = *metadata->modification_time;
+    // TODO(mtomasz): Add support for last modified time and creation time.
+    // See: crbug.com/388540.
+    file_info.last_accessed = *metadata->modification_time;  // Not supported.
+    file_info.creation_time = *metadata->modification_time;  // Not supported.
+  }
+
   file_info.is_symbolic_link = false;  // Not supported.
-  file_info.last_modified = metadata->modification_time;
-  file_info.last_accessed = metadata->modification_time;  // Not supported.
-  file_info.creation_time = metadata->modification_time;  // Not supported.
 
   BrowserThread::PostTask(BrowserThread::IO,
                           FROM_HERE,
@@ -326,7 +336,7 @@
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
       base::Bind(&GetFileInfoOnUIThread, base::Passed(&context), url, fields,
-                 base::Bind(&OnGetFileInfo, callback)));
+                 base::Bind(&OnGetFileInfo, fields, callback)));
 }
 
 void ProviderAsyncFileUtil::ReadDirectory(
diff --git a/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc b/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc
index 0cc8389..9bbefe1 100644
--- a/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc
+++ b/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc
@@ -17,6 +17,7 @@
 
 // Convert |value| into |output|. If parsing fails, then returns false.
 bool ConvertRequestValueToFileInfo(scoped_ptr<RequestValue> value,
+                                   int fields,
                                    bool root_entry,
                                    EntryMetadata* output) {
   using extensions::api::file_system_provider::EntryMetadata;
@@ -27,29 +28,40 @@
   if (!params)
     return false;
 
-  if (!ValidateIDLEntryMetadata(params->metadata, root_entry))
+  if (!ValidateIDLEntryMetadata(params->metadata, fields, root_entry))
     return false;
 
-  output->name = params->metadata.name;
-  output->is_directory = params->metadata.is_directory;
-  output->size = static_cast<int64>(*params->metadata.size);
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_NAME)
+    output->name.reset(new std::string(*params->metadata.name));
 
-  std::string input_modification_time;
-  if (!params->metadata.modification_time->additional_properties.GetString(
-          "value", &input_modification_time)) {
-    NOTREACHED();
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_IS_DIRECTORY)
+    output->is_directory.reset(new bool(*params->metadata.is_directory));
+
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_SIZE)
+    output->size.reset(new int64(static_cast<int64>(*params->metadata.size)));
+
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME) {
+    std::string input_modification_time;
+    params->metadata.modification_time->additional_properties.GetString(
+        "value", &input_modification_time);
+
+    // Allow to pass invalid modification time, since there is no way to verify
+    // it easily on any earlier stage.
+    base::Time output_modification_time;
+    base::Time::FromString(input_modification_time.c_str(),
+                           &output_modification_time);
+    output->modification_time.reset(new base::Time(output_modification_time));
   }
 
-  // Allow to pass invalid modification time, since there is no way to verify
-  // it easily on any earlier stage.
-  base::Time::FromString(input_modification_time.c_str(),
-                         &output->modification_time);
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_MIME_TYPE &&
+      params->metadata.mime_type.get()) {
+    output->mime_type.reset(new std::string(*params->metadata.mime_type.get()));
+  }
 
-  if (params->metadata.mime_type.get())
-    output->mime_type = *params->metadata.mime_type.get();
-
-  if (params->metadata.thumbnail.get())
-    output->thumbnail = *params->metadata.thumbnail.get();
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL &&
+      params->metadata.thumbnail.get()) {
+    output->thumbnail.reset(new std::string(*params->metadata.thumbnail.get()));
+  }
 
   return true;
 }
@@ -58,23 +70,43 @@
 
 bool ValidateIDLEntryMetadata(
     const extensions::api::file_system_provider::EntryMetadata& metadata,
+    int fields,
     bool root_entry) {
   using extensions::api::file_system_provider::EntryMetadata;
 
-  if (!ValidateName(metadata.name, root_entry))
-    return false;
-
-  std::string input_modification_time;
-  if (metadata.modification_time.get() &&
-      !metadata.modification_time->additional_properties.GetString(
-          "value", &input_modification_time)) {
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_IS_DIRECTORY &&
+      !metadata.is_directory.get()) {
     return false;
   }
 
-  if (metadata.thumbnail.get()) {
-    // Sanity check for the thumbnail format. Note, that another, more granural
-    // check is done in custom bindings. Note, this is an extra check only for
-    // the security reasons.
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_NAME &&
+      (!metadata.name.get() || !ValidateName(*metadata.name, root_entry))) {
+    return false;
+  }
+
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_SIZE &&
+      !metadata.size.get()) {
+    return false;
+  }
+
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME) {
+    if (!metadata.modification_time)
+      return false;
+    std::string input_modification_time;
+    if (!metadata.modification_time->additional_properties.GetString(
+            "value", &input_modification_time)) {
+      return false;
+    }
+  }
+
+  // Empty MIME type is not allowed, but for backward compability it's
+  // accepted. Note, that there is a warning in custom bindings for it.
+
+  if (fields & ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL &&
+      metadata.thumbnail.get()) {
+    // Sanity check for the thumbnail format. Note, that another, more
+    // granural check is done in custom bindings. Note, this is an extra check
+    // only for the security reasons.
     const std::string expected_prefix = "data:";
     std::string thumbnail_prefix =
         metadata.thumbnail.get()->substr(0, expected_prefix.size());
@@ -118,6 +150,14 @@
   options.file_system_id = file_system_info_.file_system_id();
   options.request_id = request_id;
   options.entry_path = entry_path_.AsUTF8Unsafe();
+  options.is_directory =
+      fields_ & ProvidedFileSystemInterface::METADATA_FIELD_IS_DIRECTORY;
+  options.name = fields_ & ProvidedFileSystemInterface::METADATA_FIELD_NAME;
+  options.size = fields_ & ProvidedFileSystemInterface::METADATA_FIELD_SIZE;
+  options.modification_time =
+      fields_ & ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME;
+  options.mime_type =
+      fields_ & ProvidedFileSystemInterface::METADATA_FIELD_MIME_TYPE;
   options.thumbnail =
       fields_ & ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL;
 
@@ -134,8 +174,8 @@
                             bool has_more) {
   scoped_ptr<EntryMetadata> metadata(new EntryMetadata);
   const bool convert_result = ConvertRequestValueToFileInfo(
-      result.Pass(), entry_path_.AsUTF8Unsafe() == FILE_PATH_LITERAL("/"),
-      metadata.get());
+      result.Pass(), fields_,
+      entry_path_.AsUTF8Unsafe() == FILE_PATH_LITERAL("/"), metadata.get());
 
   if (!convert_result) {
     LOG(ERROR) << "Failed to parse a response for the get metadata operation.";
@@ -152,6 +192,7 @@
                           base::File::Error error) {
   callback_.Run(make_scoped_ptr<EntryMetadata>(NULL), error);
 }
+
 }  // namespace operations
 }  // namespace file_system_provider
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/file_system_provider/operations/get_metadata.h b/chrome/browser/chromeos/file_system_provider/operations/get_metadata.h
index 06252d4..cfb8e87 100644
--- a/chrome/browser/chromeos/file_system_provider/operations/get_metadata.h
+++ b/chrome/browser/chromeos/file_system_provider/operations/get_metadata.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_GET_METADATA_H_
 #define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_GET_METADATA_H_
 
+#include <string>
+
 #include "base/files/file.h"
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/chromeos/file_system_provider/operations/operation.h"
@@ -29,6 +31,7 @@
 // name or empty for non-root), then returns false.
 bool ValidateIDLEntryMetadata(
     const extensions::api::file_system_provider::EntryMetadata& metadata,
+    int fields,
     bool root_entry);
 
 // Checks whether the passed name is valid or not.
diff --git a/chrome/browser/chromeos/file_system_provider/operations/get_metadata_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/get_metadata_unittest.cc
index 59ec1aa..8f89f59 100644
--- a/chrome/browser/chromeos/file_system_provider/operations/get_metadata_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/operations/get_metadata_unittest.cc
@@ -129,73 +129,91 @@
   // Correct metadata for non-root.
   {
     EntryMetadata metadata;
-    metadata.name = kValidFileName;
+    metadata.name.reset(new std::string(kValidFileName));
     metadata.modification_time.reset(new ModificationTime());
     metadata.modification_time->additional_properties.SetString(
         "value", "invalid-date-time");  // Invalid modification time is OK.
     metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
-    EXPECT_TRUE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
+    EXPECT_TRUE(ValidateIDLEntryMetadata(
+        metadata,
+        ProvidedFileSystemInterface::METADATA_FIELD_NAME |
+            ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME |
+            ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
+        false /* root_path */));
   }
 
   // Correct metadata for non-root (without thumbnail).
   {
     EntryMetadata metadata;
-    metadata.name = kValidFileName;
+    metadata.name.reset(new std::string(kValidFileName));
     metadata.modification_time.reset(new ModificationTime());
     metadata.modification_time->additional_properties.SetString(
         "value", "invalid-date-time");  // Invalid modification time is OK.
-    EXPECT_TRUE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
+    EXPECT_TRUE(ValidateIDLEntryMetadata(
+        metadata,
+        ProvidedFileSystemInterface::METADATA_FIELD_NAME |
+            ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME |
+            ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
+        false /* root_path */));
   }
 
   // Correct metadata for root.
   {
     EntryMetadata metadata;
-    metadata.name = "";
+    metadata.name.reset(new std::string());
     metadata.modification_time.reset(new ModificationTime());
     metadata.modification_time->additional_properties.SetString(
         "value", "invalid-date-time");  // Invalid modification time is OK.
-    EXPECT_TRUE(ValidateIDLEntryMetadata(metadata, true /* root_path */));
+    EXPECT_TRUE(ValidateIDLEntryMetadata(
+        metadata,
+        ProvidedFileSystemInterface::METADATA_FIELD_NAME |
+            ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME |
+            ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
+        true /* root_path */));
   }
 
   // Invalid characters in the name.
   {
     EntryMetadata metadata;
-    metadata.name = "hello/world";
-    metadata.modification_time.reset(new ModificationTime());
-    metadata.modification_time->additional_properties.SetString(
-        "value", "invalid-date-time");  // Invalid modification time is OK.
-    metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
-    EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
+    metadata.name.reset(new std::string("hello/world"));
+    EXPECT_FALSE(ValidateIDLEntryMetadata(
+        metadata, ProvidedFileSystemInterface::METADATA_FIELD_NAME,
+        false /* root_path */));
   }
 
   // Empty name for non-root.
   {
     EntryMetadata metadata;
-    metadata.name = "";
-    metadata.modification_time.reset(new ModificationTime());
-    metadata.modification_time->additional_properties.SetString(
-        "value", "invalid-date-time");  // Invalid modification time is OK.
-    metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
-    EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
+    metadata.name.reset(new std::string());
+    EXPECT_FALSE(ValidateIDLEntryMetadata(
+        metadata, ProvidedFileSystemInterface::METADATA_FIELD_NAME,
+        false /* root_path */));
   }
 
-  // Missing last modification time is allowed.
+  // Missing last modification time.
   {
     EntryMetadata metadata;
-    metadata.name = kValidFileName;
-    metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
-    EXPECT_TRUE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
+    EXPECT_FALSE(ValidateIDLEntryMetadata(
+        metadata, ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME,
+        false /* root_path */));
   }
 
   // Invalid thumbnail.
   {
     EntryMetadata metadata;
-    metadata.name = kValidFileName;
-    metadata.modification_time.reset(new ModificationTime());
-    metadata.modification_time->additional_properties.SetString(
-        "value", "invalid-date-time");  // Invalid modification time is OK.
     metadata.thumbnail.reset(new std::string("http://invalid-scheme"));
-    EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
+    EXPECT_FALSE(ValidateIDLEntryMetadata(
+        metadata, ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
+        false /* root_path */));
+  }
+
+  // Empty string for thumbnail.
+  {
+    EntryMetadata metadata;
+    metadata.thumbnail.reset(new std::string());
+    EXPECT_FALSE(ValidateIDLEntryMetadata(
+        metadata, ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
+        false /* root_path */));
   }
 }
 
@@ -258,7 +276,12 @@
 
   GetMetadata get_metadata(
       NULL, file_system_info_, base::FilePath(kDirectoryPath),
-      ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
+      ProvidedFileSystemInterface::METADATA_FIELD_IS_DIRECTORY |
+          ProvidedFileSystemInterface::METADATA_FIELD_NAME |
+          ProvidedFileSystemInterface::METADATA_FIELD_SIZE |
+          ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME |
+          ProvidedFileSystemInterface::METADATA_FIELD_MIME_TYPE |
+          ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
       base::Bind(&CallbackLogger::OnGetMetadata,
                  base::Unretained(&callback_logger)));
   get_metadata.SetDispatchEventImplForTesting(
@@ -297,14 +320,14 @@
   EXPECT_EQ(base::File::FILE_OK, event->result());
 
   const EntryMetadata* metadata = event->metadata();
-  EXPECT_FALSE(metadata->is_directory);
-  EXPECT_EQ(4096, metadata->size);
+  EXPECT_FALSE(*metadata->is_directory);
+  EXPECT_EQ(4096, *metadata->size);
   base::Time expected_time;
   EXPECT_TRUE(
       base::Time::FromString("Thu Apr 24 00:46:52 UTC 2014", &expected_time));
-  EXPECT_EQ(expected_time, metadata->modification_time);
-  EXPECT_EQ(kMimeType, metadata->mime_type);
-  EXPECT_EQ(kThumbnail, metadata->thumbnail);
+  EXPECT_EQ(expected_time, *metadata->modification_time);
+  EXPECT_EQ(kMimeType, *metadata->mime_type);
+  EXPECT_EQ(kThumbnail, *metadata->thumbnail);
 }
 
 TEST_F(FileSystemProviderOperationsGetMetadataTest, OnSuccess_InvalidMetadata) {
@@ -313,7 +336,12 @@
 
   GetMetadata get_metadata(
       NULL, file_system_info_, base::FilePath(kDirectoryPath),
-      ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
+      ProvidedFileSystemInterface::METADATA_FIELD_IS_DIRECTORY |
+          ProvidedFileSystemInterface::METADATA_FIELD_NAME |
+          ProvidedFileSystemInterface::METADATA_FIELD_SIZE |
+          ProvidedFileSystemInterface::METADATA_FIELD_MODIFICATION_TIME |
+          ProvidedFileSystemInterface::METADATA_FIELD_MIME_TYPE |
+          ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
       base::Bind(&CallbackLogger::OnGetMetadata,
                  base::Unretained(&callback_logger)));
   get_metadata.SetDispatchEventImplForTesting(
diff --git a/chrome/browser/chromeos/file_system_provider/operations/read_directory.cc b/chrome/browser/chromeos/file_system_provider/operations/read_directory.cc
index 72ec917..2f77ff7 100644
--- a/chrome/browser/chromeos/file_system_provider/operations/read_directory.cc
+++ b/chrome/browser/chromeos/file_system_provider/operations/read_directory.cc
@@ -29,12 +29,17 @@
 
   for (size_t i = 0; i < params->entries.size(); ++i) {
     const linked_ptr<EntryMetadata> entry_metadata = params->entries[i];
-    if (!ValidateIDLEntryMetadata(*entry_metadata, false /* root_entry */))
+    if (!ValidateIDLEntryMetadata(
+            *entry_metadata,
+            ProvidedFileSystemInterface::METADATA_FIELD_IS_DIRECTORY |
+                ProvidedFileSystemInterface::METADATA_FIELD_NAME,
+            false /* root_entry */)) {
       return false;
+    }
 
     storage::DirectoryEntry output_entry;
-    output_entry.is_directory = entry_metadata->is_directory;
-    output_entry.name = entry_metadata->name;
+    output_entry.is_directory = *entry_metadata->is_directory;
+    output_entry.name = *entry_metadata->name;
 
     output->push_back(output_entry);
   }
@@ -65,6 +70,10 @@
   options.request_id = request_id;
   options.directory_path = directory_path_.AsUTF8Unsafe();
 
+  // Request only is_directory and name metadata fields.
+  options.is_directory = true;
+  options.name = true;
+
   return SendEvent(
       request_id,
       extensions::events::FILE_SYSTEM_PROVIDER_ON_READ_DIRECTORY_REQUESTED,
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.cc
index f91d8d8e..4f0fca9 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.cc
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.cc
@@ -7,15 +7,13 @@
 namespace chromeos {
 namespace file_system_provider {
 
-EntryMetadata::EntryMetadata() : is_directory(false), size(0) {
-}
+EntryMetadata::EntryMetadata() {}
 
 EntryMetadata::~EntryMetadata() {
 }
 
-OpenedFile::OpenedFile(const base::FilePath& file_path, OpenFileMode& mode)
-    : file_path(file_path), mode(mode) {
-}
+OpenedFile::OpenedFile(const base::FilePath& file_path, OpenFileMode mode)
+    : file_path(file_path), mode(mode) {}
 
 OpenedFile::OpenedFile() : mode(OPEN_FILE_MODE_READ) {
 }
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h b/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h
index a611b9a..acb6ace 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_INTERFACE_H_
 #define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_PROVIDED_FILE_SYSTEM_INTERFACE_H_
 
+#include <map>
 #include <string>
 #include <vector>
 
@@ -40,12 +41,14 @@
   EntryMetadata();
   ~EntryMetadata();
 
-  bool is_directory;
-  std::string name;
-  int64 size;
-  base::Time modification_time;
-  std::string mime_type;
-  std::string thumbnail;
+  // All of the metadata fields are optional. All strings which are set, are
+  // non-empty.
+  scoped_ptr<bool> is_directory;
+  scoped_ptr<std::string> name;
+  scoped_ptr<int64> size;
+  scoped_ptr<base::Time> modification_time;
+  scoped_ptr<std::string> mime_type;
+  scoped_ptr<std::string> thumbnail;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(EntryMetadata);
@@ -64,7 +67,7 @@
 
 // Contains information about an opened file.
 struct OpenedFile {
-  OpenedFile(const base::FilePath& file_path, OpenFileMode& mode);
+  OpenedFile(const base::FilePath& file_path, OpenFileMode mode);
   OpenedFile();
   ~OpenedFile();
 
@@ -83,10 +86,15 @@
 // with either a success or an error.
 class ProvidedFileSystemInterface {
  public:
-  // Extra fields to be fetched with metadata.
+  // Fields to be fetched with metadata.
   enum MetadataField {
-    METADATA_FIELD_DEFAULT = 0,
-    METADATA_FIELD_THUMBNAIL = 1 << 0
+    METADATA_FIELD_NONE = 0,
+    METADATA_FIELD_IS_DIRECTORY = 1 << 0,
+    METADATA_FIELD_NAME = 1 << 1,
+    METADATA_FIELD_SIZE = 1 << 2,
+    METADATA_FIELD_MODIFICATION_TIME = 1 << 3,
+    METADATA_FIELD_MIME_TYPE = 1 << 4,
+    METADATA_FIELD_THUMBNAIL = 1 << 5
   };
 
   // Callback for OpenFile(). In case of an error, file_handle is equal to 0
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index 83b988b..627ee4b 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -208,6 +208,7 @@
     chromeos::switches::kDbusStub,
     chromeos::switches::kDbusUnstubClients,
     chromeos::switches::kDisableLoginAnimations,
+    chromeos::switches::kEnableArc,
     chromeos::switches::kEnableConsumerManagement,
     chromeos::switches::kEnterpriseEnableForcedReEnrollment,
     chromeos::switches::kHasChromeOSDiamondKey,
diff --git a/chrome/browser/download/download_danger_prompt.cc b/chrome/browser/download/download_danger_prompt.cc
index f581e42..b6f0a09 100644
--- a/chrome/browser/download/download_danger_prompt.cc
+++ b/chrome/browser/download/download_danger_prompt.cc
@@ -6,19 +6,24 @@
 
 #include "base/bind.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/download/chrome_download_manager_delegate.h"
 #include "chrome/browser/download/download_stats.h"
 #include "chrome/browser/extensions/api/experience_sampling_private/experience_sampling.h"
+#include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/ui/tab_modal_confirm_dialog.h"
 #include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
+#include "chrome/common/safe_browsing/csd.pb.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/download_danger_type.h"
 #include "content/public/browser/download_item.h"
 #include "ui/base/l10n/l10n_util.h"
 
 using extensions::ExperienceSamplingEvent;
+using safe_browsing::ClientSafeBrowsingReportRequest;
 
 namespace {
 
@@ -80,10 +85,8 @@
   // ExperienceSampling: A malicious download warning is being shown to the
   // user, so we start a new SamplingEvent and track it.
   sampling_event_.reset(new ExperienceSamplingEvent(
-      ExperienceSamplingEvent::kDownloadDangerPrompt,
-      download->GetURL(),
-      download->GetReferrerUrl(),
-      download->GetBrowserContext()));
+      ExperienceSamplingEvent::kDownloadDangerPrompt, download->GetURL(),
+      download->GetReferrerUrl(), download->GetBrowserContext()));
 }
 
 DownloadDangerPromptImpl::~DownloadDangerPromptImpl() {
@@ -94,8 +97,12 @@
 
 void DownloadDangerPromptImpl::InvokeActionForTesting(Action action) {
   switch (action) {
-    case ACCEPT: Accept(); break;
-    case CANCEL: Cancel(); break;
+    case ACCEPT:
+      Accept();
+      break;
+    case CANCEL:
+      Cancel();
+      break;
     case DISMISS:
       RunDone(DISMISS);
       Cancel();
@@ -140,7 +147,7 @@
             IDS_PROMPT_DANGEROUS_DOWNLOAD,
             download_->GetFileNameToReportUser().LossyDisplayName());
       }
-      case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: // Fall through
+      case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:  // Fall through
       case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
       case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
         return l10n_util::GetStringFUTF16(
@@ -170,10 +177,10 @@
       case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
       case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
         return l10n_util::GetStringUTF16(
-            IDS_PROMPT_CONFIRM_KEEP_MALICIOUS_DOWNLOAD_LEAD) +
-            base::ASCIIToUTF16("\n\n") +
-            l10n_util::GetStringUTF16(
-                IDS_PROMPT_CONFIRM_KEEP_MALICIOUS_DOWNLOAD_BODY);
+                   IDS_PROMPT_CONFIRM_KEEP_MALICIOUS_DOWNLOAD_LEAD) +
+               base::ASCIIToUTF16("\n\n") +
+               l10n_util::GetStringUTF16(
+                   IDS_PROMPT_CONFIRM_KEEP_MALICIOUS_DOWNLOAD_BODY);
       }
       default: {
         return l10n_util::GetStringUTF16(
@@ -240,6 +247,11 @@
   OnDone done = done_;
   done_.Reset();
   if (download_ != NULL) {
+    if (!download_->GetURL().is_empty() &&
+        !download_->GetBrowserContext()->IsOffTheRecord()) {
+      SendSafeBrowsingDownloadRecoveryReport(
+          action == DownloadDangerPrompt::ACCEPT, download_->GetURL());
+    }
     download_->RemoveObserver(this);
     download_ = NULL;
   }
@@ -256,10 +268,27 @@
     content::WebContents* web_contents,
     bool show_context,
     const OnDone& done) {
-  DownloadDangerPromptImpl* prompt = new DownloadDangerPromptImpl(
-      item, web_contents, show_context, done);
+  DownloadDangerPromptImpl* prompt =
+      new DownloadDangerPromptImpl(item, web_contents, show_context, done);
   // |prompt| will be deleted when the dialog is done.
   TabModalConfirmDialog::Create(prompt, web_contents);
   return prompt;
 }
 #endif
+
+void DownloadDangerPrompt::SendSafeBrowsingDownloadRecoveryReport(
+    bool did_proceed,
+    const GURL& url) {
+  safe_browsing::SafeBrowsingService* sb_service =
+      g_browser_process->safe_browsing_service();
+  ClientSafeBrowsingReportRequest report;
+  report.set_type(ClientSafeBrowsingReportRequest::MALICIOUS_DOWNLOAD_RECOVERY);
+  report.set_url(url.spec());
+  report.set_did_proceed(did_proceed);
+
+  std::string serialized_report;
+  if (report.SerializeToString(&serialized_report))
+    sb_service->SendDownloadRecoveryReport(serialized_report);
+  else
+    DLOG(ERROR) << "Unable to serialize the threat report.";
+}
diff --git a/chrome/browser/download/download_danger_prompt.h b/chrome/browser/download/download_danger_prompt.h
index e1b5c612..4ca7bd2a 100644
--- a/chrome/browser/download/download_danger_prompt.h
+++ b/chrome/browser/download/download_danger_prompt.h
@@ -7,6 +7,8 @@
 
 #include "base/callback_forward.h"
 
+class GURL;
+
 namespace content {
 class DownloadItem;
 class WebContents;
@@ -37,15 +39,23 @@
   // caller does not own the object and receive no guarantees about lifetime.
   // If |show_context|, then the prompt message will contain some information
   // about the download and its danger; otherwise it won't.
-  static DownloadDangerPrompt* Create(
-      content::DownloadItem* item,
-      content::WebContents* web_contents,
-      bool show_context,
-      const OnDone& done);
+  static DownloadDangerPrompt* Create(content::DownloadItem* item,
+                                      content::WebContents* web_contents,
+                                      bool show_context,
+                                      const OnDone& done);
 
   // Only to be used by tests. Subclasses must override to manually call the
   // respective button click handler.
   virtual void InvokeActionForTesting(Action action) = 0;
+
+ protected:
+  // Sends download recovery report to safe browsing backend.
+  // Since it only records download url (DownloadItem::GetURL()) and user's
+  // action (click through or not), it isn't gated by user's extended reporting
+  // preference (i.e. prefs::kSafeBrowsingExtendedReportingEnabled). We
+  // should not put any extra information in this report.
+  static void SendSafeBrowsingDownloadRecoveryReport(bool did_proceed,
+                                                     const GURL& url);
 };
 
 #endif  // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_DANGER_PROMPT_H_
diff --git a/chrome/browser/download/download_danger_prompt_browsertest.cc b/chrome/browser/download/download_danger_prompt_browsertest.cc
index 2b33e0e7..a0cde01e4 100644
--- a/chrome/browser/download/download_danger_prompt_browsertest.cc
+++ b/chrome/browser/download/download_danger_prompt_browsertest.cc
@@ -6,10 +6,13 @@
 #include "base/files/file_path.h"
 #include "chrome/browser/download/download_danger_prompt.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/safe_browsing/database_manager.h"
+#include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/safe_browsing/csd.pb.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/test/mock_download_item.h"
@@ -23,17 +26,71 @@
 using ::testing::Return;
 using ::testing::ReturnRef;
 using ::testing::SaveArg;
+using safe_browsing::ClientSafeBrowsingReportRequest;
+using safe_browsing::SafeBrowsingService;
+
+const char kTestDownloadUrl[] = "http://evildownload.com";
+
+class FakeSafeBrowsingService : public SafeBrowsingService {
+ public:
+  FakeSafeBrowsingService() {}
+
+  void SendDownloadRecoveryReport(const std::string& report) override {
+    report_ = report;
+  }
+
+  std::string GetDownloadRecoveryReport() const { return report_; }
+
+ protected:
+  ~FakeSafeBrowsingService() override {}
+
+ private:
+  std::string report_;
+};
+
+// Factory that creates FakeSafeBrowsingService instances.
+class TestSafeBrowsingServiceFactory
+    : public safe_browsing::SafeBrowsingServiceFactory {
+ public:
+  TestSafeBrowsingServiceFactory() : fake_safe_browsing_service_(nullptr) {}
+  ~TestSafeBrowsingServiceFactory() override {}
+
+  SafeBrowsingService* CreateSafeBrowsingService() override {
+    if (!fake_safe_browsing_service_) {
+      fake_safe_browsing_service_ = new FakeSafeBrowsingService();
+    }
+    return fake_safe_browsing_service_.get();
+  }
+
+  scoped_refptr<FakeSafeBrowsingService> fake_safe_browsing_service() {
+    return fake_safe_browsing_service_;
+  }
+
+ private:
+  scoped_refptr<FakeSafeBrowsingService> fake_safe_browsing_service_;
+};
 
 class DownloadDangerPromptTest : public InProcessBrowserTest {
  public:
   DownloadDangerPromptTest()
-    : prompt_(NULL),
-      expected_action_(DownloadDangerPrompt::CANCEL),
-      did_receive_callback_(false) {
-  }
+      : prompt_(nullptr),
+        expected_action_(DownloadDangerPrompt::CANCEL),
+        did_receive_callback_(false),
+        test_safe_browsing_factory_(new TestSafeBrowsingServiceFactory()),
+        report_sent_(false) {}
 
   ~DownloadDangerPromptTest() override {}
 
+  void SetUp() override {
+    SafeBrowsingService::RegisterFactory(test_safe_browsing_factory_.get());
+    InProcessBrowserTest::SetUp();
+  }
+
+  void TearDown() override {
+    SafeBrowsingService::RegisterFactory(nullptr);
+    InProcessBrowserTest::TearDown();
+  }
+
   // Opens a new tab and waits for navigations to finish. If there are pending
   // navigations, the constrained prompt might be dismissed when the navigation
   // completes.
@@ -49,7 +106,10 @@
     did_receive_callback_ = false;
     expected_action_ = expected_action;
     SetUpDownloadItemExpectations();
+    SetUpSafeBrowsingReportExpectations(expected_action ==
+                                        DownloadDangerPrompt::ACCEPT);
     CreatePrompt();
+    report_sent_ = false;
   }
 
   void VerifyExpectations() {
@@ -59,10 +119,16 @@
     EXPECT_TRUE(did_receive_callback_);
     EXPECT_FALSE(prompt_);
     testing::Mock::VerifyAndClearExpectations(&download_);
+    if (report_sent_) {
+      EXPECT_EQ(expected_serialized_report_,
+                test_safe_browsing_factory_->fake_safe_browsing_service()
+                    ->GetDownloadRecoveryReport());
+    }
   }
 
   void SimulatePromptAction(DownloadDangerPrompt::Action action) {
     prompt_->InvokeActionForTesting(action);
+    report_sent_ = true;
   }
 
   content::MockDownloadItem& download() { return download_; }
@@ -77,6 +143,15 @@
         .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL));
   }
 
+  void SetUpSafeBrowsingReportExpectations(bool did_proceed) {
+    ClientSafeBrowsingReportRequest expected_report;
+    expected_report.set_url(GURL(kTestDownloadUrl).spec());
+    expected_report.set_type(
+        ClientSafeBrowsingReportRequest::MALICIOUS_DOWNLOAD_RECOVERY);
+    expected_report.set_did_proceed(did_proceed);
+    expected_report.SerializeToString(&expected_serialized_report_);
+  }
+
   void CreatePrompt() {
     prompt_ = DownloadDangerPrompt::Create(
         &download_,
@@ -90,13 +165,16 @@
     EXPECT_FALSE(did_receive_callback_);
     EXPECT_EQ(expected_action_, action);
     did_receive_callback_ = true;
-    prompt_ = NULL;
+    prompt_ = nullptr;
   }
 
   content::MockDownloadItem download_;
   DownloadDangerPrompt* prompt_;
   DownloadDangerPrompt::Action expected_action_;
   bool did_receive_callback_;
+  scoped_ptr<TestSafeBrowsingServiceFactory> test_safe_browsing_factory_;
+  std::string expected_serialized_report_;
+  bool report_sent_;
 
   DISALLOW_COPY_AND_ASSIGN(DownloadDangerPromptTest);
 };
@@ -109,7 +187,8 @@
 #endif
 IN_PROC_BROWSER_TEST_F(DownloadDangerPromptTest, MAYBE_TestAll) {
   // ExperienceSampling: Set default actions for DownloadItem methods we need.
-  ON_CALL(download(), GetURL()).WillByDefault(ReturnRef(GURL::EmptyGURL()));
+  GURL download_url(kTestDownloadUrl);
+  ON_CALL(download(), GetURL()).WillByDefault(ReturnRef(download_url));
   ON_CALL(download(), GetReferrerUrl())
       .WillByDefault(ReturnRef(GURL::EmptyGURL()));
   ON_CALL(download(), GetBrowserContext())
diff --git a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
index c263ce7..21aeda0b 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
@@ -518,21 +518,16 @@
                                          content_type,
                                          true /* overwrite */);
   }
-  ScopedVector<net::UploadElementReader> element_readers;
-  element_readers.push_back(new net::UploadBytesElementReader(
-      &(bytes_1[0]), bytes_1.size()));
-  element_readers.push_back(
-      new net::UploadFileElementReader(
-                                       base::ThreadTaskRunnerHandle::Get()
-                                       .get(),
-                                       base::FilePath(),
-                                       0,
-                                       0,
-                                       base::Time()));
-  element_readers.push_back(
-      new net::UploadBytesElementReader(&(bytes_2[0]), bytes_2.size()));
+  std::vector<scoped_ptr<net::UploadElementReader>> element_readers;
+  element_readers.push_back(make_scoped_ptr(
+      new net::UploadBytesElementReader(&(bytes_1[0]), bytes_1.size())));
+  element_readers.push_back(make_scoped_ptr(new net::UploadFileElementReader(
+      base::ThreadTaskRunnerHandle::Get().get(), base::FilePath(), 0, 0,
+      base::Time())));
+  element_readers.push_back(make_scoped_ptr(
+      new net::UploadBytesElementReader(&(bytes_2[0]), bytes_2.size())));
   request->set_upload(make_scoped_ptr(
-      new net::ElementsUploadDataStream(element_readers.Pass(), 0)));
+      new net::ElementsUploadDataStream(std::move(element_readers), 0)));
   ipc_sender_.PushTask(base::Bind(&base::DoNothing));
   request->Start();
 }
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index 1e4a738..56a5178e 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -27,6 +27,7 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/features.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/crx_file/id_util.h"
@@ -382,7 +383,7 @@
 }
 
 void ComponentLoader::AddGoogleNowExtension() {
-#if defined(ENABLE_GOOGLE_NOW)
+#if BUILDFLAG(ENABLE_GOOGLE_NOW)
   const char kEnablePrefix[] = "Enable";
   const char kFieldTrialName[] = "GoogleNow";
   std::string enable_prefix(kEnablePrefix);
@@ -418,7 +419,7 @@
   } else {
     DeleteData(google_now_manifest_id, root_directory);
   }
-#endif  // defined(ENABLE_GOOGLE_NOW)
+#endif  // BUILDFLAG(ENABLE_GOOGLE_NOW)
 }
 
 #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/policy/cloud/test_request_interceptor.cc b/chrome/browser/policy/cloud/test_request_interceptor.cc
index 9f3a516..458fc06 100644
--- a/chrome/browser/policy/cloud/test_request_interceptor.cc
+++ b/chrome/browser/policy/cloud/test_request_interceptor.cc
@@ -83,7 +83,7 @@
   const net::UploadDataStream* stream = request->get_upload();
   if (!stream)
     return false;
-  const ScopedVector<net::UploadElementReader>* readers =
+  const std::vector<scoped_ptr<net::UploadElementReader>>* readers =
       stream->GetElementReaders();
   if (!readers || readers->size() != 1u)
     return false;
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index 04d5e9f3..8566442 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/first_run/first_run.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/common/features.h"
 #include "chrome/common/pref_names.h"
 #include "components/browser_sync/browser/profile_sync_service.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
@@ -98,7 +99,7 @@
   registry->RegisterDictionaryPref(prefs::kSafeBrowsingIncidentsSent);
   registry->RegisterBooleanPref(
       prefs::kSafeBrowsingExtendedReportingOptInAllowed, true);
-#if defined(ENABLE_GOOGLE_NOW)
+#if BUILDFLAG(ENABLE_GOOGLE_NOW)
   registry->RegisterBooleanPref(prefs::kGoogleGeolocationAccessEnabled, false);
 #endif
   // This pref is intentionally outside the above #if. That flag corresponds
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn
index a5949a21..14de709 100644
--- a/chrome/browser/resources/BUILD.gn
+++ b/chrome/browser/resources/BUILD.gn
@@ -2,10 +2,12 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//chrome/common/features.gni")
 import("//tools/grit/grit_rule.gni")
 
 grit("memory_internals_resources") {
   source = "memory_internals_resources.grd"
+  defines = chrome_grit_defines
   outputs = [
     "grit/memory_internals_resources.h",
     "memory_internals_resources.pak",
@@ -15,6 +17,7 @@
 
 grit("net_internals_resources") {
   source = "net_internals_resources.grd"
+  defines = chrome_grit_defines
   outputs = [
     "grit/net_internals_resources.h",
     "net_internals_resources.pak",
@@ -24,6 +27,7 @@
 
 grit("invalidations_resources") {
   source = "invalidations_resources.grd"
+  defines = chrome_grit_defines
   outputs = [
     "grit/invalidations_resources.h",
     "invalidations_resources.pak",
@@ -33,6 +37,7 @@
 
 grit("password_manager_internals_resources") {
   source = "password_manager_internals_resources.grd"
+  defines = chrome_grit_defines
   outputs = [
     "grit/password_manager_internals_resources.h",
     "password_manager_internals_resources.pak",
@@ -42,6 +47,7 @@
 
 grit("signin_internals_resources") {
   source = "signin_internals_resources.grd"
+  defines = chrome_grit_defines
   outputs = [
     "grit/signin_internals_resources.h",
     "signin_internals_resources.pak",
@@ -51,6 +57,7 @@
 
 grit("translate_internals_resources") {
   source = "translate_internals_resources.grd"
+  defines = chrome_grit_defines
   outputs = [
     "grit/translate_internals_resources.h",
     "translate_internals_resources.pak",
@@ -71,6 +78,7 @@
 if (!is_ios) {
   grit("component_extension_resources") {
     source = "component_extension_resources.grd"
+    defines = chrome_grit_defines
     outputs = [
       "grit/component_extension_resources.h",
       "grit/component_extension_resources_map.cc",
@@ -82,6 +90,7 @@
 
   grit("settings_resources") {
     source = "settings/settings_resources.grd"
+    defines = chrome_grit_defines
     outputs = [
       "grit/settings_resources.h",
       "grit/settings_resources_map.cc",
@@ -93,6 +102,7 @@
 
   grit("options_resources") {
     source = "options_resources.grd"
+    defines = chrome_grit_defines
     outputs = [
       "grit/options_resources.h",
       "options_resources.pak",
@@ -102,6 +112,7 @@
 
   grit("options_test_resources") {
     source = "options_test_resources.grd"
+    defines = chrome_grit_defines
     outputs = [
       "grit/options_test_resources.h",
       "options_test_resources.pak",
@@ -111,6 +122,7 @@
 
   grit("quota_internals_resources") {
     source = "quota_internals_resources.grd"
+    defines = chrome_grit_defines
     outputs = [
       "grit/quota_internals_resources.h",
       "quota_internals_resources.pak",
@@ -120,6 +132,7 @@
 
   grit("sync_file_system_internals_resources") {
     source = "sync_file_system_internals_resources.grd"
+    defines = chrome_grit_defines
     outputs = [
       "grit/sync_file_system_internals_resources.h",
       "sync_file_system_internals_resources.pak",
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index 84328d5..0f32155b 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -645,4 +645,20 @@
 #endif
 }
 
+void SafeBrowsingService::SendDownloadRecoveryReport(
+    const std::string& report) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::Bind(&SafeBrowsingService::OnSendDownloadRecoveryReport, this,
+                 report));
+}
+
+void SafeBrowsingService::OnSendDownloadRecoveryReport(
+    const std::string& report) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (ping_manager())
+    ping_manager()->ReportThreatDetails(report);
+}
+
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h
index 00b13e1..8ab58313 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.h
+++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -165,6 +165,9 @@
   scoped_ptr<StateSubscription> RegisterStateCallback(
       const base::Callback<void(void)>& callback);
 
+  // Sends serialized download recovery report to backend.
+  virtual void SendDownloadRecoveryReport(const std::string& report);
+
  protected:
   // Creates the safe browsing service.  Need to initialize before using.
   SafeBrowsingService();
@@ -239,6 +242,8 @@
   // starts or stops the service accordingly.
   void RefreshState();
 
+  void OnSendDownloadRecoveryReport(const std::string& report);
+
   // The factory used to instanciate a SafeBrowsingService object.
   // Useful for tests, so they can provide their own implementation of
   // SafeBrowsingService.
diff --git a/chrome/browser/sessions/better_session_restore_browsertest.cc b/chrome/browser/sessions/better_session_restore_browsertest.cc
index 7b15d5ca6..ff8a81d 100644
--- a/chrome/browser/sessions/better_session_restore_browsertest.cc
+++ b/chrome/browser/sessions/better_session_restore_browsertest.cc
@@ -98,7 +98,7 @@
     const net::UploadDataStream* upload_data = request->get_upload();
     last_upload_bytes_.clear();
     if (upload_data) {
-      const ScopedVector<net::UploadElementReader>* readers =
+      const std::vector<scoped_ptr<net::UploadElementReader>>* readers =
           upload_data->GetElementReaders();
       if (readers) {
         for (size_t i = 0; i < readers->size(); ++i) {
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine.cc
index af08422..6fbd5947 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_engine.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_engine.cc
@@ -75,6 +75,8 @@
           GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction),
           GURL(google_apis::DriveApiUrlGenerator::
                kBaseDownloadUrlForProduction),
+          GURL(google_apis::DriveApiUrlGenerator::
+               kBaseThumbnailUrlForProduction),
           std::string() /* custom_user_agent */));
 }
 
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index be6d20f..e8124cc4 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -5,6 +5,7 @@
 import("//build/config/crypto.gni")
 import("//build/config/features.gni")
 import("//build/config/ui.gni")
+import("//chrome/common/features.gni")
 
 gypi_values = exec_script("//build/gypi_to_gn.py",
                           [ rebase_path("../../chrome_browser_ui.gypi") ],
diff --git a/chrome/browser/ui/cocoa/passwords/account_chooser_view_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/account_chooser_view_controller_unittest.mm
index 26ae628..e8bbc0a 100644
--- a/chrome/browser/ui/cocoa/passwords/account_chooser_view_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/passwords/account_chooser_view_controller_unittest.mm
@@ -70,7 +70,6 @@
     ManagePasswordsControllerTest::SetUp();
     delegate_.reset([[ContentViewDelegateMock alloc] init]);
     avatar_manager_.reset([[AccountAvatarFetcherTestManager alloc] init]);
-    ui_controller()->SetState(password_manager::ui::CREDENTIAL_REQUEST_STATE);
   }
 
   ContentViewDelegateMock* delegate() { return delegate_.get(); }
@@ -83,7 +82,7 @@
     if (!controller_) {
       controller_.reset(
           [[ManagePasswordsBubbleAccountChooserViewController alloc]
-              initWithModel:model()
+              initWithModel:GetModelAndCreateIfNull()
               avatarManager:avatar_manager()
                    delegate:delegate()]);
       [controller_ loadView];
@@ -99,15 +98,11 @@
 };
 
 TEST_F(ManagePasswordsBubbleAccountChooserViewControllerTest, ConfiguresViews) {
-  ScopedVector<autofill::PasswordForm> local_forms;
+  ScopedVector<const autofill::PasswordForm> local_forms;
   local_forms.push_back(Credential("pizza"));
-  ScopedVector<autofill::PasswordForm> federated_forms;
+  ScopedVector<const autofill::PasswordForm> federated_forms;
   federated_forms.push_back(Credential("taco"));
-  EXPECT_TRUE(ui_controller()->OnChooseCredentials(
-      local_forms.Pass(),
-      federated_forms.Pass(),
-      GURL("http://example.com"),
-      base::Callback<void(const password_manager::CredentialInfo&)>()));
+  SetUpAccountChooser(local_forms.Pass(), federated_forms.Pass());
   // Trigger creation of controller and check the views.
   NSTableView* view = controller().credentialsView;
   ASSERT_NSNE(nil, view);
@@ -129,14 +124,12 @@
 
 TEST_F(ManagePasswordsBubbleAccountChooserViewControllerTest,
        ForwardsAvatarFetchToManager) {
-  ScopedVector<autofill::PasswordForm> local_forms;
-  local_forms.push_back(Credential("taco"));
-  local_forms.back()->icon_url = GURL("http://foo");
-  EXPECT_TRUE(ui_controller()->OnChooseCredentials(
-      local_forms.Pass(),
-      ScopedVector<autofill::PasswordForm>(),
-      GURL("http://example.com"),
-      base::Callback<void(const password_manager::CredentialInfo&)>()));
+  ScopedVector<const autofill::PasswordForm> local_forms;
+  scoped_ptr<autofill::PasswordForm> form = Credential("taco");
+  form->icon_url = GURL("http://foo");
+  local_forms.push_back(form.Pass());
+  SetUpAccountChooser(local_forms.Pass(),
+                      ScopedVector<const autofill::PasswordForm>());
   // Trigger creation of the controller and check the fetched URLs.
   controller();
   EXPECT_FALSE(avatar_manager().fetchedAvatars.empty());
@@ -148,48 +141,47 @@
 
 TEST_F(ManagePasswordsBubbleAccountChooserViewControllerTest,
        SelectingCredentialInformsModelAndClosesDialog) {
-  ScopedVector<autofill::PasswordForm> local_forms;
+  ScopedVector<const autofill::PasswordForm> local_forms;
   local_forms.push_back(Credential("pizza"));
-  ScopedVector<autofill::PasswordForm> federated_forms;
+  ScopedVector<const autofill::PasswordForm> federated_forms;
   federated_forms.push_back(Credential("taco"));
-  EXPECT_TRUE(ui_controller()->OnChooseCredentials(
-      local_forms.Pass(),
-      federated_forms.Pass(),
-      GURL("http://example.com"),
-      base::Callback<void(const password_manager::CredentialInfo&)>()));
+  SetUpAccountChooser(local_forms.Pass(), federated_forms.Pass());
+  EXPECT_CALL(*ui_controller(),
+              ChooseCredential(
+                  *Credential("taco"),
+                  password_manager::CredentialType::CREDENTIAL_TYPE_FEDERATED));
   [controller().credentialsView
           selectRowIndexes:[NSIndexSet indexSetWithIndex:1]
       byExtendingSelection:NO];
   EXPECT_TRUE(delegate().dismissed);
-  EXPECT_TRUE(ui_controller()->choose_credential());
-  EXPECT_EQ(base::ASCIIToUTF16("taco"),
-            ui_controller()->chosen_credential().username_value);
 }
 
 TEST_F(ManagePasswordsBubbleAccountChooserViewControllerTest,
        SelectingNopeDismissesDialog) {
-  ScopedVector<autofill::PasswordForm> local_forms;
+  ScopedVector<const autofill::PasswordForm> local_forms;
   local_forms.push_back(Credential("pizza"));
-  EXPECT_TRUE(ui_controller()->OnChooseCredentials(
-      local_forms.Pass(), ScopedVector<autofill::PasswordForm>(),
-      GURL("http://example.com"),
-      base::Callback<void(const password_manager::CredentialInfo&)>()));
+  SetUpAccountChooser(local_forms.Pass(),
+                      ScopedVector<const autofill::PasswordForm>());
   [controller().cancelButton performClick:nil];
   EXPECT_TRUE(delegate().dismissed);
 }
 
 TEST_F(ManagePasswordsBubbleAccountChooserViewControllerTest,
        SelectingSettingsShowsSettingsPage) {
+  SetUpAccountChooser(ScopedVector<const autofill::PasswordForm>(),
+                      ScopedVector<const autofill::PasswordForm>());
   BubbleCombobox* moreButton = controller().moreButton;
   EXPECT_TRUE(moreButton);
+  EXPECT_CALL(*ui_controller(), NavigateToPasswordManagerSettingsPage());
   [[moreButton menu] performActionForItemAtIndex:
                          AccountChooserMoreComboboxModel::INDEX_SETTINGS];
-  EXPECT_TRUE(ui_controller()->navigated_to_settings_page());
   EXPECT_TRUE(delegate().dismissed);
 }
 
 TEST_F(ManagePasswordsBubbleAccountChooserViewControllerTest,
        SelectingLearnMoreShowsHelpCenterArticle) {
+  SetUpAccountChooser(ScopedVector<const autofill::PasswordForm>(),
+                      ScopedVector<const autofill::PasswordForm>());
   BubbleCombobox* moreButton = controller().moreButton;
   EXPECT_TRUE(moreButton);
   [[moreButton menu] performActionForItemAtIndex:
diff --git a/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.h b/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.h
index 845c0d8..510a93ea 100644
--- a/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.h
+++ b/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.h
@@ -24,7 +24,15 @@
   void SetUp() override;
 
   ManagePasswordsUIControllerMock* ui_controller() { return ui_controller_; }
-  ManagePasswordsBubbleModel* model();
+  ManagePasswordsBubbleModel* GetModelAndCreateIfNull();
+
+  // Sets the appropriate state for ManagePasswordsBubbleModel.
+  void SetUpPendingState();
+  void SetUpConfirmationState();
+  void SetUpManageState();
+  void SetUpAccountChooser(
+      ScopedVector<const autofill::PasswordForm> local,
+      ScopedVector<const autofill::PasswordForm> federations);
 
   // An opportunity for tests to override the constructor parameter of
   // ManagePasswordsBubbleModel.
diff --git a/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.mm b/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.mm
index 61be389..b6a7c9f5 100644
--- a/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.mm
+++ b/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.mm
@@ -10,6 +10,13 @@
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "content/public/test/web_contents_tester.h"
 
+namespace {
+const char kSiteOrigin[] = "http://example.com/login";
+}
+
+using testing::Return;
+using testing::ReturnRef;
+
 ManagePasswordsControllerTest::
     ManagePasswordsControllerTest() {
 }
@@ -24,8 +31,8 @@
   // |test_web_contents_| and therefore accessible to the model.
   test_web_contents_.reset(
       content::WebContentsTester::CreateTestWebContents(profile(), NULL));
-  ui_controller_ =
-      new ManagePasswordsUIControllerMock(test_web_contents_.get());
+  ui_controller_ = new testing::NiceMock<ManagePasswordsUIControllerMock>(
+      test_web_contents_.get());
   PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse(
       profile(), password_manager::BuildPasswordStore<
                      content::BrowserContext,
@@ -33,7 +40,7 @@
 }
 
 ManagePasswordsBubbleModel*
-ManagePasswordsControllerTest::model() {
+ManagePasswordsControllerTest::GetModelAndCreateIfNull() {
   if (!model_) {
     model_.reset(new ManagePasswordsBubbleModel(test_web_contents_.get(),
                                                 GetDisplayReason()));
@@ -41,6 +48,54 @@
   return model_.get();
 }
 
+void ManagePasswordsControllerTest::SetUpPendingState() {
+  autofill::PasswordForm form;
+  EXPECT_CALL(*ui_controller_, GetPendingPassword()).WillOnce(ReturnRef(form));
+  std::vector<const autofill::PasswordForm*> forms;
+  EXPECT_CALL(*ui_controller_, GetCurrentForms()).WillOnce(ReturnRef(forms));
+  GURL origin(kSiteOrigin);
+  EXPECT_CALL(*ui_controller_, GetOrigin()).WillOnce(ReturnRef(origin));
+  EXPECT_CALL(*ui_controller_, GetState())
+      .WillOnce(Return(password_manager::ui::PENDING_PASSWORD_STATE));
+  GetModelAndCreateIfNull();
+  ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_));
+}
+
+void ManagePasswordsControllerTest::SetUpConfirmationState() {
+  GURL origin(kSiteOrigin);
+  EXPECT_CALL(*ui_controller_, GetOrigin()).WillOnce(ReturnRef(origin));
+  EXPECT_CALL(*ui_controller_, GetState())
+      .WillOnce(Return(password_manager::ui::CONFIRMATION_STATE));
+  GetModelAndCreateIfNull();
+  ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_));
+}
+
+void ManagePasswordsControllerTest::SetUpManageState() {
+  std::vector<const autofill::PasswordForm*> forms;
+  EXPECT_CALL(*ui_controller_, GetCurrentForms()).WillOnce(ReturnRef(forms));
+  GURL origin(kSiteOrigin);
+  EXPECT_CALL(*ui_controller_, GetOrigin()).WillOnce(ReturnRef(origin));
+  EXPECT_CALL(*ui_controller_, GetState())
+      .WillOnce(Return(password_manager::ui::MANAGE_STATE));
+  GetModelAndCreateIfNull();
+  ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_));
+}
+
+void ManagePasswordsControllerTest::SetUpAccountChooser(
+    ScopedVector<const autofill::PasswordForm> local,
+    ScopedVector<const autofill::PasswordForm> federations) {
+  EXPECT_CALL(*ui_controller_, GetCurrentForms())
+      .WillOnce(ReturnRef(local.get()));
+  EXPECT_CALL(*ui_controller_, GetFederatedForms())
+      .WillOnce(ReturnRef(federations.get()));
+  EXPECT_CALL(*ui_controller_, GetState())
+      .WillOnce(Return(password_manager::ui::CREDENTIAL_REQUEST_STATE));
+  GURL origin(kSiteOrigin);
+  EXPECT_CALL(*ui_controller_, GetOrigin()).WillOnce(ReturnRef(origin));
+  GetModelAndCreateIfNull();
+  ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_));
+}
+
 ManagePasswordsBubbleModel::DisplayReason
 ManagePasswordsControllerTest::GetDisplayReason() const {
   return ManagePasswordsBubbleModel::AUTOMATIC;
diff --git a/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller_unittest.mm
index 6c6783e..6aa5990 100644
--- a/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/passwords/confirmation_password_saved_view_controller_unittest.mm
@@ -25,7 +25,7 @@
   void SetUp() override {
     ManagePasswordsControllerTest::SetUp();
     delegate_.reset([[ContentViewDelegateMock alloc] init]);
-    ui_controller()->SetState(password_manager::ui::CONFIRMATION_STATE);
+    SetUpConfirmationState();
   }
 
   ContentViewDelegateMock* delegate() { return delegate_.get(); }
@@ -33,7 +33,7 @@
   ManagePasswordsBubbleConfirmationViewController* controller() {
     if (!controller_) {
       controller_.reset([[ManagePasswordsBubbleConfirmationViewController alloc]
-          initWithModel:model()
+          initWithModel:GetModelAndCreateIfNull()
                delegate:delegate()]);
       [controller_ loadView];
     }
@@ -54,9 +54,9 @@
 
 TEST_F(ManagePasswordsBubbleConfirmationViewControllerTest,
        ShouldOpenPasswordsAndDismissWhenLinkClicked) {
+  EXPECT_CALL(*ui_controller(), NavigateToPasswordManagerSettingsPage());
   [controller().confirmationText clickedOnLink:@"about:blank" atIndex:0];
   EXPECT_TRUE([delegate() dismissed]);
-  EXPECT_TRUE(ui_controller()->navigated_to_settings_page());
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/cocoa/passwords/manage_passwords_view_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/manage_passwords_view_controller_unittest.mm
index 2045c7d..2689adb 100644
--- a/chrome/browser/ui/cocoa/passwords/manage_passwords_view_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/passwords/manage_passwords_view_controller_unittest.mm
@@ -15,6 +15,9 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
 
+using testing::Return;
+using testing::ReturnRef;
+
 namespace {
 
 class ManagePasswordsBubbleManageViewControllerTest
@@ -25,7 +28,6 @@
   void SetUp() override {
     ManagePasswordsControllerTest::SetUp();
     delegate_.reset([[ContentViewDelegateMock alloc] init]);
-    ui_controller()->SetState(password_manager::ui::MANAGE_STATE);
   }
 
   ContentViewDelegateMock* delegate() { return delegate_.get(); }
@@ -33,7 +35,7 @@
   ManagePasswordsBubbleManageViewController* controller() {
     if (!controller_) {
       controller_.reset([[ManagePasswordsBubbleManageViewController alloc]
-          initWithModel:model()
+          initWithModel:GetModelAndCreateIfNull()
                delegate:delegate()]);
       [controller_ loadView];
     }
@@ -52,20 +54,23 @@
 
 TEST_F(ManagePasswordsBubbleManageViewControllerTest,
        ShouldDismissWhenDoneClicked) {
+  SetUpManageState();
   [controller().doneButton performClick:nil];
   EXPECT_TRUE([delegate() dismissed]);
 }
 
 TEST_F(ManagePasswordsBubbleManageViewControllerTest,
        ShouldOpenPasswordsWhenManageClicked) {
+  SetUpManageState();
+  EXPECT_CALL(*ui_controller(), NavigateToPasswordManagerSettingsPage());
   [controller().manageButton performClick:nil];
   EXPECT_TRUE([delegate() dismissed]);
-  EXPECT_TRUE(ui_controller()->navigated_to_settings_page());
 }
 
 TEST_F(ManagePasswordsBubbleManageViewControllerTest,
        ShouldShowNoPasswordsWhenNoPasswordsExistForSite) {
-  EXPECT_TRUE(model()->local_credentials().empty());
+  SetUpManageState();
+  EXPECT_TRUE(GetModelAndCreateIfNull()->local_credentials().empty());
   EXPECT_TRUE([controller() noPasswordsView]);
   EXPECT_FALSE([controller() passwordsListController]);
 }
@@ -73,23 +78,26 @@
 TEST_F(ManagePasswordsBubbleManageViewControllerTest,
        ShouldShowAllPasswordItemsWhenPasswordsExistForSite) {
   // Add a few password entries.
-  autofill::PasswordFormMap map;
-  scoped_ptr<autofill::PasswordForm> form1(new autofill::PasswordForm);
-  form1->username_value = base::ASCIIToUTF16("username1");
-  form1->password_value = base::ASCIIToUTF16("password1");
-  map.insert(base::ASCIIToUTF16("username1"), form1.Pass());
+  autofill::PasswordForm form1;
+  form1.username_value = base::ASCIIToUTF16("username1");
+  form1.password_value = base::ASCIIToUTF16("password1");
 
-  scoped_ptr<autofill::PasswordForm> form2(new autofill::PasswordForm);
-  form2->username_value = base::ASCIIToUTF16("username2");
-  form2->password_value = base::ASCIIToUTF16("password2");
-  map.insert(base::ASCIIToUTF16("username2"), form2.Pass());
+  autofill::PasswordForm form2;
+  form2.username_value = base::ASCIIToUTF16("username2");
+  form2.password_value = base::ASCIIToUTF16("password2");
 
   // Add the entries to the model.
-  ui_controller()->OnPasswordAutofilled(map, map.begin()->second->origin);
-  model()->set_state(password_manager::ui::MANAGE_STATE);
+  std::vector<const autofill::PasswordForm*> forms;
+  forms.push_back(&form1);
+  forms.push_back(&form2);
+  EXPECT_CALL(*ui_controller(), GetCurrentForms()).WillOnce(ReturnRef(forms));
+  GURL origin;
+  EXPECT_CALL(*ui_controller(), GetOrigin()).WillOnce(ReturnRef(origin));
+  EXPECT_CALL(*ui_controller(), GetState())
+      .WillOnce(Return(password_manager::ui::MANAGE_STATE));
 
   // Check the view state.
-  EXPECT_FALSE(model()->local_credentials().empty());
+  EXPECT_FALSE(GetModelAndCreateIfNull()->local_credentials().empty());
   ASSERT_TRUE([controller() passwordsListController]);
   EXPECT_FALSE([controller() noPasswordsView]);
   NSArray* items = [[controller() passwordsListController] itemViews];
diff --git a/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa_unittest.mm b/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa_unittest.mm
index 7e1c456..6f35b926 100644
--- a/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa_unittest.mm
+++ b/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa_unittest.mm
@@ -31,6 +31,9 @@
 #include "testing/gtest_mac.h"
 #include "testing/platform_test.h"
 
+using testing::Return;
+using testing::ReturnRef;
+
 class ManagePasswordsBubbleCocoaTest : public CocoaProfileTest {
  public:
   void SetUp() override {
@@ -44,19 +47,15 @@
     // |test_web_contents_| and therefore accessible to the model. It should be
     // done before AppendWebContents() so the real ManagePasswordsUIController
     // isn't created.
-    ManagePasswordsUIControllerMock* ui_controller =
-        new ManagePasswordsUIControllerMock(test_web_contents_);
+    new testing::NiceMock<ManagePasswordsUIControllerMock>(test_web_contents_);
+    EXPECT_CALL(*UIController(), GetState())
+        .WillOnce(Return(password_manager::ui::INACTIVE_STATE));
     browser()->tab_strip_model()->AppendWebContents(
         test_web_contents_, /*foreground=*/true);
     PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse(
         profile(), password_manager::BuildPasswordStore<
                        content::BrowserContext,
                        testing::NiceMock<password_manager::MockPasswordStore>>);
-    // Set the initial state.
-    ScopedVector<autofill::PasswordForm> forms;
-    forms.push_back(new autofill::PasswordForm);
-    forms.back()->origin = GURL("http://example.com");
-    ui_controller->PretendSubmittedPassword(forms.Pass());
   }
 
   content::WebContents* CreateWebContents() {
@@ -65,6 +64,17 @@
   }
 
   void ShowBubble(bool user_action) {
+    ManagePasswordsUIControllerMock* mock = UIController();
+    ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(mock));
+    autofill::PasswordForm form;
+    EXPECT_CALL(*mock, GetPendingPassword()).WillOnce(ReturnRef(form));
+    std::vector<const autofill::PasswordForm*> forms;
+    EXPECT_CALL(*mock, GetCurrentForms()).WillOnce(ReturnRef(forms));
+    GURL origin;
+    EXPECT_CALL(*mock, GetOrigin()).WillOnce(ReturnRef(origin));
+    EXPECT_CALL(*mock, GetState())
+        .WillOnce(Return(password_manager::ui::PENDING_PASSWORD_STATE));
+
     TabDialogs::FromWebContents(test_web_contents_)
         ->ShowManagePasswordsBubble(user_action);
     if (ManagePasswordsBubbleCocoa::instance()) {
@@ -73,6 +83,7 @@
           [ManagePasswordsBubbleCocoa::instance()->controller_ window]);
       [bubbleWindow setAllowedAnimations:info_bubble::kAnimateNone];
     }
+    ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(mock));
   }
 
   void CloseBubble() {
@@ -84,6 +95,11 @@
     return bubble ? [bubble->controller_ window] : nil;
   }
 
+  ManagePasswordsUIControllerMock* UIController() {
+    return static_cast<ManagePasswordsUIControllerMock*>(
+        PasswordsModelDelegateFromWebContents(test_web_contents_));
+  }
+
   ManagePasswordsBubbleController* controller() {
     ManagePasswordsBubbleCocoa* bubble = ManagePasswordsBubbleCocoa::instance();
     return bubble ? bubble->controller_ : nil;
@@ -91,7 +107,7 @@
 
   ManagePasswordsIconCocoa* icon() {
     return static_cast<ManagePasswordsIconCocoa*>(
-      ManagePasswordsBubbleCocoa::instance()->icon_);
+        ManagePasswordsBubbleCocoa::instance()->icon_);
   }
 
  private:
@@ -131,15 +147,22 @@
   TabStripModel* tabStripModel = browser()->tab_strip_model();
   EXPECT_EQ(0, tabStripModel->active_index());
 
-  // Open a second tab and make it active.
+  // Open a second tab as inactive.
   content::WebContents* webContents2 = CreateWebContents();
-  tabStripModel->AppendWebContents(webContents2, /*foreground=*/true);
-  EXPECT_EQ(1, tabStripModel->active_index());
+  new testing::StrictMock<ManagePasswordsUIControllerMock>(webContents2);
+  tabStripModel->AppendWebContents(webContents2, /*foreground=*/false);
+  EXPECT_EQ(0, tabStripModel->active_index());
   EXPECT_EQ(2, tabStripModel->count());
 
   // Try to show the bubble on the inactive tab. Nothing should happen.
-  ShowBubble(false);
+  TabDialogs::FromWebContents(tabStripModel->GetWebContentsAt(1))
+      ->ShowManagePasswordsBubble(false);
   EXPECT_FALSE(ManagePasswordsBubbleCocoa::instance());
+
+  // Show the bubble for the active tab.
+  ShowBubble(false);
+  EXPECT_TRUE(ManagePasswordsBubbleCocoa::instance());
+  EXPECT_TRUE([bubbleWindow() isVisible]);
 }
 
 TEST_F(ManagePasswordsBubbleCocoaTest, HideBubbleOnChangedState) {
diff --git a/chrome/browser/ui/cocoa/passwords/passwords_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/passwords_bubble_controller_unittest.mm
index ca219da7..510da060 100644
--- a/chrome/browser/ui/cocoa/passwords/passwords_bubble_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/passwords/passwords_bubble_controller_unittest.mm
@@ -34,7 +34,7 @@
     if (!controller_) {
       controller_ = [[ManagePasswordsBubbleController alloc]
           initWithParentWindow:browser()->window()->GetNativeWindow()
-                         model:model()];
+                         model:GetModelAndCreateIfNull()];
     }
     return controller_;
   }
@@ -48,13 +48,13 @@
 };
 
 TEST_F(ManagePasswordsBubbleControllerTest, PendingStateShouldHavePendingView) {
-  ui_controller()->SetState(password_manager::ui::PENDING_PASSWORD_STATE);
+  SetUpPendingState();
   EXPECT_EQ([ManagePasswordsBubblePendingViewController class],
             [[controller() currentController] class]);
 }
 
 TEST_F(ManagePasswordsBubbleControllerTest, DismissingShouldCloseWindow) {
-  ui_controller()->SetState(password_manager::ui::PENDING_PASSWORD_STATE);
+  SetUpPendingState();
   [controller() showWindow:nil];
 
   // Turn off animations so that closing happens immediately.
@@ -68,7 +68,7 @@
 }
 
 TEST_F(ManagePasswordsBubbleControllerTest, ManageStateShouldHaveManageView) {
-  ui_controller()->SetState(password_manager::ui::MANAGE_STATE);
+  SetUpManageState();
   EXPECT_EQ([ManagePasswordsBubbleManageViewController class],
             [[controller() currentController] class]);
 }
diff --git a/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm
index 43753d7..cc35b99 100644
--- a/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm
@@ -43,16 +43,16 @@
 
   void SetUpManageState(
       const std::vector<const autofill::PasswordForm*>& forms) {
-    ui_controller()->SetState(password_manager::ui::MANAGE_STATE);
+    ManagePasswordsControllerTest::SetUpManageState();
     controller_.reset([[PasswordsListViewController alloc]
-        initWithModel:model()
+        initWithModel:GetModelAndCreateIfNull()
                 forms:forms]);
   }
 
   void SetUpPendingState(const autofill::PasswordForm* form) {
-    ui_controller()->SetState(password_manager::ui::PENDING_PASSWORD_STATE);
+    ManagePasswordsControllerTest::SetUpPendingState();
     controller_.reset([[PasswordsListViewController alloc]
-        initWithModel:model()
+        initWithModel:GetModelAndCreateIfNull()
                 forms:std::vector<const autofill::PasswordForm*>(1, form)]);
   }
 
diff --git a/chrome/browser/ui/cocoa/passwords/pending_password_view_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/pending_password_view_controller_unittest.mm
index 85c69184..dd204b7 100644
--- a/chrome/browser/ui/cocoa/passwords/pending_password_view_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/passwords/pending_password_view_controller_unittest.mm
@@ -26,7 +26,7 @@
   void SetUp() override {
     ManagePasswordsControllerTest::SetUp();
     delegate_.reset([[ContentViewDelegateMock alloc] init]);
-    ui_controller()->SetState(password_manager::ui::PENDING_PASSWORD_STATE);
+    SetUpPendingState();
   }
 
   ContentViewDelegateMock* delegate() { return delegate_.get(); }
@@ -34,7 +34,7 @@
   ManagePasswordsBubblePendingViewController* controller() {
     if (!controller_) {
       controller_.reset([[ManagePasswordsBubblePendingViewController alloc]
-          initWithModel:model()
+          initWithModel:GetModelAndCreateIfNull()
                delegate:delegate()]);
       [controller_ loadView];
     }
@@ -48,29 +48,29 @@
 
 TEST_F(ManagePasswordsBubblePendingViewControllerTest,
        ShouldSavePasswordAndDismissWhenSaveClicked) {
+  EXPECT_CALL(*ui_controller(), SavePassword());
+  EXPECT_CALL(*ui_controller(), NeverSavePassword()).Times(0);
   [controller().saveButton performClick:nil];
 
   EXPECT_TRUE([delegate() dismissed]);
-  EXPECT_TRUE(ui_controller()->saved_password());
-  EXPECT_FALSE(ui_controller()->never_saved_password());
 }
 
 TEST_F(ManagePasswordsBubblePendingViewControllerTest,
        ShouldNeverAndDismissWhenNeverClicked) {
+  EXPECT_CALL(*ui_controller(), SavePassword()).Times(0);
+  EXPECT_CALL(*ui_controller(), NeverSavePassword());
   [controller().neverButton performClick:nil];
 
   EXPECT_TRUE([delegate() dismissed]);
-  EXPECT_FALSE(ui_controller()->saved_password());
-  EXPECT_TRUE(ui_controller()->never_saved_password());
 }
 
 TEST_F(ManagePasswordsBubblePendingViewControllerTest,
        ShouldDismissWhenCrossClicked) {
+  EXPECT_CALL(*ui_controller(), SavePassword()).Times(0);
+  EXPECT_CALL(*ui_controller(), NeverSavePassword()).Times(0);
   [controller().closeButton performClick:nil];
 
   EXPECT_TRUE([delegate() dismissed]);
-  EXPECT_FALSE(ui_controller()->saved_password());
-  EXPECT_FALSE(ui_controller()->never_saved_password());
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
index a1abf30..b8354944 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
@@ -11,6 +11,7 @@
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/time/default_clock.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
@@ -73,15 +74,16 @@
     content::WebContents* web_contents,
     DisplayReason display_reason)
     : content::WebContentsObserver(web_contents),
+      password_overridden_(false),
       display_disposition_(metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING),
       dismissal_reason_(metrics_util::NO_DIRECT_INTERACTION),
-      update_password_submission_event_(metrics_util::NO_UPDATE_SUBMISSION) {
+      update_password_submission_event_(metrics_util::NO_UPDATE_SUBMISSION),
+      clock_(new base::DefaultClock) {
   PasswordsModelDelegate* delegate =
       PasswordsModelDelegateFromWebContents(web_contents);
 
   origin_ = delegate->GetOrigin();
   state_ = delegate->GetState();
-  password_overridden_ = delegate->IsPasswordOverridden();
   if (state_ == password_manager::ui::PENDING_PASSWORD_STATE ||
       state_ == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE) {
     pending_password_ = delegate->GetPendingPassword();
@@ -143,13 +145,15 @@
   } else if (state_ == password_manager::ui::PENDING_PASSWORD_STATE) {
     interaction_stats_.origin_domain = origin_.GetOrigin();
     interaction_stats_.username_value = pending_password_.username_value;
-    interaction_stats_.update_time = base::Time::Now();
     password_manager::InteractionsStats* stats =
         delegate->GetCurrentInteractionStats();
     if (stats) {
-      // TODO(vasilii): DCHECK that username and origin are the same.
+      DCHECK_EQ(interaction_stats_.username_value, stats->username_value);
+      DCHECK_EQ(interaction_stats_.origin_domain, stats->origin_domain);
       interaction_stats_.dismissal_count = stats->dismissal_count;
     }
+  } else if (state_ == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE) {
+    password_overridden_ = delegate->IsPasswordOverridden();
   }
 
   manage_link_ =
@@ -220,6 +224,7 @@
             std::numeric_limits<decltype(
                 interaction_stats_.dismissal_count)>::max())
           interaction_stats_.dismissal_count++;
+        interaction_stats_.update_time = clock_->Now();
         password_manager::PasswordStore* password_store =
             PasswordStoreFactory::GetForProfile(
                 profile, ServiceAccessType::EXPLICIT_ACCESS)
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.h b/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
index 00ee2abc..ad74c570 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_MODEL_H_
 
 #include "base/memory/scoped_vector.h"
+#include "base/time/clock.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/statistics_table.h"
@@ -135,19 +136,12 @@
   bool ShouldShowAutoSigninWarmWelcome() const;
 
 #if defined(UNIT_TEST)
-  // Gets and sets the reason the bubble was displayed.
-  password_manager::metrics_util::UIDisplayDisposition display_disposition()
-      const {
-    return display_disposition_;
-  }
-
   // Gets the reason the bubble was dismissed.
   password_manager::metrics_util::UIDismissalReason dismissal_reason() const {
     return dismissal_reason_;
   }
 
-  // State setter.
-  void set_state(password_manager::ui::State state) { state_ = state; }
+  void set_clock(scoped_ptr<base::Clock> clock) { clock_ = clock.Pass(); }
 #endif
 
  private:
@@ -187,6 +181,9 @@
   // Current statistics for the save password bubble;
   password_manager::InteractionsStats interaction_stats_;
 
+  // Used to retrieve the current time, in base::Time units.
+  scoped_ptr<base::Clock> clock_;
+
   DISALLOW_COPY_AND_ASSIGN(ManagePasswordsBubbleModel);
 };
 
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
index 1cec681..6af21fd 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/histogram_tester.h"
+#include "base/test/simple_test_clock.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/profile_sync_service_mock.h"
@@ -31,11 +32,13 @@
 using password_bubble_experiment::kSmartLockBrandingSavePromptOnlyGroupName;
 using ::testing::AnyNumber;
 using ::testing::Return;
+using ::testing::ReturnRef;
 using ::testing::_;
 
 namespace {
 
 const char kSiteOrigin[] = "http://example.com/login";
+const char kUsername[] = "Admin";
 const char kUIDismissalReasonMetric[] = "PasswordManager.UIDismissalReason";
 
 class TestSyncService : public ProfileSyncServiceMock {
@@ -71,36 +74,11 @@
   return make_scoped_ptr(new TestSyncService(static_cast<Profile*>(context)));
 }
 
-// TODO(vabr): Merge the two mocks together. http://crbug.com/546604
-class ManagePasswordsUIControllerMockWithMockNavigation
-    : public ManagePasswordsUIControllerMock {
- public:
-  explicit ManagePasswordsUIControllerMockWithMockNavigation(
-      content::WebContents* contents)
-      : ManagePasswordsUIControllerMock(contents) {}
-
-  ~ManagePasswordsUIControllerMockWithMockNavigation() override {}
-
-  MOCK_METHOD0(NavigateToPasswordManagerSettingsPage, void());
-  MOCK_METHOD0(NavigateToExternalPasswordManager, void());
-  MOCK_METHOD0(NavigateToSmartLockHelpPage, void());
-  MOCK_CONST_METHOD0(GetCurrentInteractionStats,
-                     password_manager::InteractionsStats*());
-};
-
-// TODO(vasilii): get rid of the matcher when it's possible to test the whole
-// InteractionsStats.
-MATCHER_P(DissmisalCountIs, count, "") {
-  return count == arg.dismissal_count;
-}
-
 }  // namespace
 
 class ManagePasswordsBubbleModelTest : public ::testing::Test {
  public:
-  ManagePasswordsBubbleModelTest()
-      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
-        field_trials_(nullptr) {}
+  ManagePasswordsBubbleModelTest() : field_trials_(nullptr) {}
   ~ManagePasswordsBubbleModelTest() override = default;
 
   void SetUp() override {
@@ -108,7 +86,7 @@
         content::WebContentsTester::CreateTestWebContents(&profile_, nullptr));
     // Create the test UIController here so that it's bound to
     // |test_web_contents_| and therefore accessible to the model.
-    new testing::StrictMock<ManagePasswordsUIControllerMockWithMockNavigation>(
+    new testing::StrictMock<ManagePasswordsUIControllerMock>(
         test_web_contents_.get());
     PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse(
         profile(),
@@ -134,255 +112,265 @@
             .get());
   }
 
-  password_manager::InteractionsStats GetTestStats() {
-    password_manager::InteractionsStats result;
-    result.origin_domain = GURL(kSiteOrigin);
-    result.username_value = base::ASCIIToUTF16("username");
-    result.dismissal_count = 5;
-    result.update_time = base::Time::FromTimeT(1);
-    return result;
-  }
-
- protected:
-  void SetUpWithState(password_manager::ui::State state,
-                      ManagePasswordsBubbleModel::DisplayReason reason) {
-    ManagePasswordsUIControllerMock* mock = controller();
-    mock->SetState(state);
-    model_.reset(
-        new ManagePasswordsBubbleModel(test_web_contents_.get(), reason));
-    mock->UnsetState();
-  }
-
-  void PretendPasswordWaiting() {
-    SetUpWithState(password_manager::ui::PENDING_PASSWORD_STATE,
-                   ManagePasswordsBubbleModel::AUTOMATIC);
-  }
-
-  void PretendUpdatePasswordWaiting() {
-    SetUpWithState(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE,
-                   ManagePasswordsBubbleModel::AUTOMATIC);
-  }
-
-  void PretendCredentialsWaiting() {
-    SetUpWithState(password_manager::ui::CREDENTIAL_REQUEST_STATE,
-                   ManagePasswordsBubbleModel::AUTOMATIC);
-  }
-
-  void PretendAutoSigningIn() {
-    SetUpWithState(password_manager::ui::AUTO_SIGNIN_STATE,
-                   ManagePasswordsBubbleModel::AUTOMATIC);
-  }
-
-  void PretendManagingPasswords() {
-    SetUpWithState(password_manager::ui::MANAGE_STATE,
-                   ManagePasswordsBubbleModel::USER_ACTION);
-  }
-
-  ManagePasswordsUIControllerMockWithMockNavigation* controller() {
-    return static_cast<ManagePasswordsUIControllerMockWithMockNavigation*>(
-        ManagePasswordsUIController::FromWebContents(test_web_contents_.get()));
+  ManagePasswordsUIControllerMock* controller() {
+    return static_cast<ManagePasswordsUIControllerMock*>(
+        PasswordsModelDelegateFromWebContents(test_web_contents_.get()));
   }
 
   content::WebContents* test_web_contents() { return test_web_contents_.get(); }
 
-  scoped_ptr<ManagePasswordsBubbleModel> model_;
+  ManagePasswordsBubbleModel* model() { return model_.get(); }
+
+  void SetUpWithState(password_manager::ui::State state,
+                      ManagePasswordsBubbleModel::DisplayReason reason);
+  void PretendPasswordWaiting();
+  void PretendUpdatePasswordWaiting();
+  void PretendCredentialsWaiting();
+  void PretendAutoSigningIn();
+  void PretendManagingPasswords();
+
+  void DestroyModel();
+  void DestroyModelExpectReason(
+      password_manager::metrics_util::UIDismissalReason dismissal_reason);
+
+  static password_manager::InteractionsStats GetTestStats();
+  static autofill::PasswordForm GetPendingPassword();
 
  private:
   content::TestBrowserThreadBundle thread_bundle_;
   TestingProfile profile_;
   scoped_ptr<content::WebContents> test_web_contents_;
   base::FieldTrialList field_trials_;
+  scoped_ptr<ManagePasswordsBubbleModel> model_;
 };
 
-TEST_F(ManagePasswordsBubbleModelTest, CloseWithoutInteraction) {
-  base::HistogramTester histogram_tester;
+void ManagePasswordsBubbleModelTest::SetUpWithState(
+    password_manager::ui::State state,
+    ManagePasswordsBubbleModel::DisplayReason reason) {
+  ManagePasswordsUIControllerMock* mock = controller();
+  GURL origin(kSiteOrigin);
+  EXPECT_CALL(*mock, GetOrigin()).WillOnce(ReturnRef(origin));
+  EXPECT_CALL(*mock, GetState()).WillOnce(Return(state));
+  EXPECT_CALL(*mock, OnBubbleShown());
+  model_.reset(
+      new ManagePasswordsBubbleModel(test_web_contents_.get(), reason));
+  ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(mock));
+}
+
+void ManagePasswordsBubbleModelTest::PretendPasswordWaiting() {
+  autofill::PasswordForm form = GetPendingPassword();
+  EXPECT_CALL(*controller(), GetPendingPassword()).WillOnce(ReturnRef(form));
+  std::vector<const autofill::PasswordForm*> forms;
+  EXPECT_CALL(*controller(), GetCurrentForms()).WillOnce(ReturnRef(forms));
   password_manager::InteractionsStats stats = GetTestStats();
   EXPECT_CALL(*controller(), GetCurrentInteractionStats())
       .WillOnce(Return(&stats));
-  PretendPasswordWaiting();
-  EXPECT_EQ(model_->dismissal_reason(),
-            password_manager::metrics_util::NO_DIRECT_INTERACTION);
-  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE,
-            model_->state());
-  stats.dismissal_count++;
-  EXPECT_CALL(*GetStore(),
-              AddSiteStatsImpl(DissmisalCountIs(stats.dismissal_count)));
-  model_.reset();
-  EXPECT_FALSE(controller()->saved_password());
-  EXPECT_FALSE(controller()->never_saved_password());
+  SetUpWithState(password_manager::ui::PENDING_PASSWORD_STATE,
+                 ManagePasswordsBubbleModel::AUTOMATIC);
+}
 
-  histogram_tester.ExpectUniqueSample(
-      kUIDismissalReasonMetric,
-      password_manager::metrics_util::NO_DIRECT_INTERACTION,
-      1);
+void ManagePasswordsBubbleModelTest::PretendUpdatePasswordWaiting() {
+  autofill::PasswordForm form = GetPendingPassword();
+  EXPECT_CALL(*controller(), GetPendingPassword()).WillOnce(ReturnRef(form));
+  std::vector<const autofill::PasswordForm*> forms;
+  EXPECT_CALL(*controller(), GetCurrentForms()).WillOnce(ReturnRef(forms));
+  EXPECT_CALL(*controller(), IsPasswordOverridden()).WillOnce(Return(false));
+  SetUpWithState(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE,
+                 ManagePasswordsBubbleModel::AUTOMATIC);
+}
+
+void ManagePasswordsBubbleModelTest::PretendCredentialsWaiting() {
+  std::vector<const autofill::PasswordForm*> forms;
+  EXPECT_CALL(*controller(), GetCurrentForms()).WillOnce(ReturnRef(forms));
+  EXPECT_CALL(*controller(), GetFederatedForms()).WillOnce(ReturnRef(forms));
+  SetUpWithState(password_manager::ui::CREDENTIAL_REQUEST_STATE,
+                 ManagePasswordsBubbleModel::AUTOMATIC);
+}
+
+void ManagePasswordsBubbleModelTest::PretendAutoSigningIn() {
+  autofill::PasswordForm form = GetPendingPassword();
+  EXPECT_CALL(*controller(), GetPendingPassword()).WillOnce(ReturnRef(form));
+  SetUpWithState(password_manager::ui::AUTO_SIGNIN_STATE,
+                 ManagePasswordsBubbleModel::AUTOMATIC);
+}
+
+void ManagePasswordsBubbleModelTest::PretendManagingPasswords() {
+  autofill::PasswordForm form = GetPendingPassword();
+  std::vector<const autofill::PasswordForm*> forms(1, &form);
+  EXPECT_CALL(*controller(), GetCurrentForms()).WillOnce(ReturnRef(forms));
+  SetUpWithState(password_manager::ui::MANAGE_STATE,
+                 ManagePasswordsBubbleModel::USER_ACTION);
+}
+
+void ManagePasswordsBubbleModelTest::DestroyModel() {
+  ManagePasswordsUIControllerMock* mock =
+      test_web_contents_ ? controller() : nullptr;
+  if (mock)
+    EXPECT_CALL(*mock, OnBubbleHidden());
+  model_.reset();
+  if (mock)
+    ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(mock));
+}
+
+void ManagePasswordsBubbleModelTest::DestroyModelExpectReason(
+    password_manager::metrics_util::UIDismissalReason dismissal_reason) {
+  base::HistogramTester histogram_tester;
+  DestroyModel();
+  histogram_tester.ExpectUniqueSample(kUIDismissalReasonMetric,
+                                      dismissal_reason, 1);
+}
+
+// static
+password_manager::InteractionsStats
+ManagePasswordsBubbleModelTest::GetTestStats() {
+  password_manager::InteractionsStats result;
+  result.origin_domain = GURL(kSiteOrigin).GetOrigin();
+  result.username_value = base::ASCIIToUTF16(kUsername);
+  result.dismissal_count = 5;
+  result.update_time = base::Time::FromTimeT(1);
+  return result;
+}
+
+// static
+autofill::PasswordForm ManagePasswordsBubbleModelTest::GetPendingPassword() {
+  autofill::PasswordForm form;
+  form.origin = GURL(kSiteOrigin);
+  form.signon_realm = kSiteOrigin;
+  form.username_value = base::ASCIIToUTF16(kUsername);
+  form.password_value = base::ASCIIToUTF16("12345");
+  return form;
+}
+
+TEST_F(ManagePasswordsBubbleModelTest, CloseWithoutInteraction) {
+  PretendPasswordWaiting();
+
+  EXPECT_EQ(model()->dismissal_reason(),
+            password_manager::metrics_util::NO_DIRECT_INTERACTION);
+  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE, model()->state());
+  scoped_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock);
+  base::Time now = base::Time::Now();
+  clock->SetNow(now);
+  model()->set_clock(clock.Pass());
+  password_manager::InteractionsStats stats = GetTestStats();
+  stats.dismissal_count++;
+  stats.update_time = now;
+  EXPECT_CALL(*GetStore(), AddSiteStatsImpl(stats));
+  EXPECT_CALL(*controller(), SavePassword()).Times(0);
+  EXPECT_CALL(*controller(), NeverSavePassword()).Times(0);
+  DestroyModelExpectReason(
+      password_manager::metrics_util::NO_DIRECT_INTERACTION);
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickSave) {
-  base::HistogramTester histogram_tester;
-  password_manager::InteractionsStats stats = GetTestStats();
-  EXPECT_CALL(*controller(), GetCurrentInteractionStats())
-      .WillOnce(Return(&stats));
   PretendPasswordWaiting();
-  EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(_));
-  model_->OnSaveClicked();
-  EXPECT_EQ(model_->dismissal_reason(),
-            password_manager::metrics_util::CLICKED_SAVE);
-  model_.reset();
 
-  EXPECT_TRUE(controller()->saved_password());
-  EXPECT_FALSE(controller()->never_saved_password());
-  histogram_tester.ExpectUniqueSample(
-      kUIDismissalReasonMetric,
-      password_manager::metrics_util::CLICKED_SAVE,
-      1);
+  EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin()));
+  EXPECT_CALL(*controller(), SavePassword());
+  EXPECT_CALL(*controller(), NeverSavePassword()).Times(0);
+  model()->OnSaveClicked();
+  EXPECT_EQ(model()->dismissal_reason(),
+            password_manager::metrics_util::CLICKED_SAVE);
+  DestroyModelExpectReason(password_manager::metrics_util::CLICKED_SAVE);
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickNever) {
-  base::HistogramTester histogram_tester;
-  password_manager::InteractionsStats stats = GetTestStats();
-  EXPECT_CALL(*controller(), GetCurrentInteractionStats())
-      .WillOnce(Return(&stats));
   PretendPasswordWaiting();
-  EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(_));
-  model_->OnNeverForThisSiteClicked();
-  EXPECT_EQ(model_->dismissal_reason(),
-            password_manager::metrics_util::CLICKED_NEVER);
-  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE, model_->state());
-  model_.reset();
 
-  EXPECT_FALSE(controller()->saved_password());
-  EXPECT_TRUE(controller()->never_saved_password());
-  histogram_tester.ExpectUniqueSample(
-      kUIDismissalReasonMetric,
-      password_manager::metrics_util::CLICKED_NEVER,
-      1);
+  EXPECT_CALL(*GetStore(), RemoveSiteStatsImpl(GURL(kSiteOrigin).GetOrigin()));
+  EXPECT_CALL(*controller(), SavePassword()).Times(0);
+  EXPECT_CALL(*controller(), NeverSavePassword());
+  model()->OnNeverForThisSiteClicked();
+  EXPECT_EQ(model()->dismissal_reason(),
+            password_manager::metrics_util::CLICKED_NEVER);
+  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE, model()->state());
+  DestroyModelExpectReason(password_manager::metrics_util::CLICKED_NEVER);
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickManage) {
-  base::HistogramTester histogram_tester;
   PretendManagingPasswords();
 
   EXPECT_CALL(*controller(), NavigateToPasswordManagerSettingsPage());
-  model_->OnManageLinkClicked();
+  model()->OnManageLinkClicked();
 
-  EXPECT_EQ(model_->dismissal_reason(),
+  EXPECT_EQ(model()->dismissal_reason(),
             password_manager::metrics_util::CLICKED_MANAGE);
-  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model_->state());
-  model_.reset();
-  EXPECT_FALSE(controller()->saved_password());
-  EXPECT_FALSE(controller()->never_saved_password());
-
-  histogram_tester.ExpectUniqueSample(
-      kUIDismissalReasonMetric,
-      password_manager::metrics_util::CLICKED_MANAGE,
-      1);
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model()->state());
+  DestroyModelExpectReason(password_manager::metrics_util::CLICKED_MANAGE);
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickDone) {
-  base::HistogramTester histogram_tester;
   PretendManagingPasswords();
-  model_->OnDoneClicked();
-  EXPECT_EQ(model_->dismissal_reason(),
-            password_manager::metrics_util::CLICKED_DONE);
-  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model_->state());
-  model_.reset();
-  EXPECT_FALSE(controller()->saved_password());
-  EXPECT_FALSE(controller()->never_saved_password());
 
-  histogram_tester.ExpectUniqueSample(
-      kUIDismissalReasonMetric,
-      password_manager::metrics_util::CLICKED_DONE,
-      1);
+  model()->OnDoneClicked();
+  EXPECT_EQ(model()->dismissal_reason(),
+            password_manager::metrics_util::CLICKED_DONE);
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model()->state());
+  DestroyModelExpectReason(password_manager::metrics_util::CLICKED_DONE);
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickCredential) {
-  base::HistogramTester histogram_tester;
   PretendCredentialsWaiting();
-  EXPECT_FALSE(controller()->choose_credential());
-  autofill::PasswordForm form;
-  model_->OnChooseCredentials(
-      form, password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD);
-  EXPECT_EQ(model_->dismissal_reason(),
-            password_manager::metrics_util::CLICKED_CREDENTIAL);
-  model_.reset();
-  EXPECT_FALSE(controller()->saved_password());
-  EXPECT_FALSE(controller()->never_saved_password());
-  EXPECT_TRUE(controller()->choose_credential());
 
-  histogram_tester.ExpectUniqueSample(
-      kUIDismissalReasonMetric,
-      password_manager::metrics_util::CLICKED_CREDENTIAL,
-      1);
+  autofill::PasswordForm form;
+  EXPECT_CALL(
+      *controller(),
+      ChooseCredential(
+          form, password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD));
+  model()->OnChooseCredentials(
+      form, password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD);
+  EXPECT_EQ(model()->dismissal_reason(),
+            password_manager::metrics_util::CLICKED_CREDENTIAL);
+  DestroyModelExpectReason(password_manager::metrics_util::CLICKED_CREDENTIAL);
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickCancelCredential) {
-  base::HistogramTester histogram_tester;
   PretendCredentialsWaiting();
-  EXPECT_FALSE(controller()->choose_credential());
-  model_->OnCancelClicked();
-  EXPECT_EQ(model_->dismissal_reason(),
-            password_manager::metrics_util::CLICKED_CANCEL);
-  model_.reset();
-  EXPECT_FALSE(controller()->saved_password());
-  EXPECT_FALSE(controller()->never_saved_password());
-  EXPECT_FALSE(controller()->choose_credential());
 
-  histogram_tester.ExpectUniqueSample(
-      kUIDismissalReasonMetric, password_manager::metrics_util::CLICKED_CANCEL,
-      1);
+  EXPECT_CALL(*controller(), ChooseCredential(_, _)).Times(0);
+  model()->OnCancelClicked();
+  EXPECT_EQ(model()->dismissal_reason(),
+            password_manager::metrics_util::CLICKED_CANCEL);
+  DestroyModelExpectReason(password_manager::metrics_util::CLICKED_CANCEL);
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, DismissCredential) {
-  base::HistogramTester histogram_tester;
   PretendCredentialsWaiting();
-  EXPECT_FALSE(controller()->choose_credential());
-  EXPECT_EQ(model_->dismissal_reason(),
-            password_manager::metrics_util::NO_DIRECT_INTERACTION);
-  model_.reset();
-  EXPECT_FALSE(controller()->saved_password());
-  EXPECT_FALSE(controller()->never_saved_password());
-  EXPECT_FALSE(controller()->choose_credential());
 
-  histogram_tester.ExpectUniqueSample(
-      kUIDismissalReasonMetric,
-      password_manager::metrics_util::NO_DIRECT_INTERACTION,
-      1);
+  EXPECT_CALL(*controller(), ChooseCredential(_, _)).Times(0);
+  EXPECT_EQ(model()->dismissal_reason(),
+            password_manager::metrics_util::NO_DIRECT_INTERACTION);
+  DestroyModelExpectReason(
+      password_manager::metrics_util::NO_DIRECT_INTERACTION);
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, PopupAutoSigninToast) {
-  base::HistogramTester histogram_tester;
   // Pop up the first time with the warm welcome.
   PretendAutoSigningIn();
-  EXPECT_TRUE(model_->ShouldShowAutoSigninWarmWelcome());
-  model_->OnAutoSignOKClicked();
-  EXPECT_EQ(model_->dismissal_reason(),
+
+  EXPECT_TRUE(model()->ShouldShowAutoSigninWarmWelcome());
+  model()->OnAutoSignOKClicked();
+  EXPECT_EQ(model()->dismissal_reason(),
             password_manager::metrics_util::CLICKED_OK);
-  EXPECT_FALSE(model_->ShouldShowAutoSigninWarmWelcome());
-  model_.reset();
-  histogram_tester.ExpectUniqueSample(
-      kUIDismissalReasonMetric,
-      password_manager::metrics_util::CLICKED_OK,
-      1);
+  EXPECT_FALSE(model()->ShouldShowAutoSigninWarmWelcome());
+  DestroyModelExpectReason(password_manager::metrics_util::CLICKED_OK);
 
   // Pop up the second time without the warm welcome.
   PretendAutoSigningIn();
-  EXPECT_FALSE(model_->ShouldShowAutoSigninWarmWelcome());
-  model_->OnAutoSignInToastTimeout();
-  EXPECT_EQ(model_->dismissal_reason(),
+  EXPECT_FALSE(model()->ShouldShowAutoSigninWarmWelcome());
+  model()->OnAutoSignInToastTimeout();
+  EXPECT_EQ(model()->dismissal_reason(),
             password_manager::metrics_util::AUTO_SIGNIN_TOAST_TIMEOUT);
-  model_.reset();
-  histogram_tester.ExpectBucketCount(
-      kUIDismissalReasonMetric,
-      password_manager::metrics_util::AUTO_SIGNIN_TOAST_TIMEOUT,
-      1);
+  DestroyModelExpectReason(
+      password_manager::metrics_util::AUTO_SIGNIN_TOAST_TIMEOUT);
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickUpdate) {
   PretendUpdatePasswordWaiting();
-  model_->OnUpdateClicked(autofill::PasswordForm());
-  model_.reset();
-  EXPECT_TRUE(controller()->updated_password());
-  EXPECT_FALSE(controller()->never_saved_password());
+
+  autofill::PasswordForm form;
+  EXPECT_CALL(*controller(), UpdatePassword(form));
+  model()->OnUpdateClicked(form);
+  DestroyModel();
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ShowSmartLockWarmWelcome) {
@@ -393,14 +381,14 @@
   base::FieldTrialList::CreateFieldTrial(kBrandingExperimentName,
                                          kSmartLockBrandingGroupName);
 
-  EXPECT_CALL(*controller(), GetCurrentInteractionStats())
-      .WillRepeatedly(Return(nullptr));
-  EXPECT_CALL(*GetStore(), AddSiteStatsImpl(_)).Times(AnyNumber());
   PretendPasswordWaiting();
-  EXPECT_TRUE(model_->ShouldShowGoogleSmartLockWelcome());
-  model_.reset();
+
+  EXPECT_TRUE(model()->ShouldShowGoogleSmartLockWelcome());
+  EXPECT_CALL(*GetStore(), AddSiteStatsImpl(_));
+  DestroyModel();
   PretendPasswordWaiting();
-  EXPECT_FALSE(model_->ShouldShowGoogleSmartLockWelcome());
+
+  EXPECT_FALSE(model()->ShouldShowGoogleSmartLockWelcome());
   EXPECT_TRUE(prefs()->GetBoolean(
       password_manager::prefs::kWasSavePrompFirstRunExperienceShown));
 }
@@ -413,14 +401,14 @@
   base::FieldTrialList::CreateFieldTrial(kBrandingExperimentName,
                                          kSmartLockBrandingGroupName);
 
-  EXPECT_CALL(*controller(), GetCurrentInteractionStats())
-      .WillRepeatedly(Return(nullptr));
-  EXPECT_CALL(*GetStore(), AddSiteStatsImpl(_)).Times(AnyNumber());
   PretendPasswordWaiting();
-  EXPECT_FALSE(model_->ShouldShowGoogleSmartLockWelcome());
-  model_.reset();
+
+  EXPECT_FALSE(model()->ShouldShowGoogleSmartLockWelcome());
+  EXPECT_CALL(*GetStore(), AddSiteStatsImpl(_));
+  DestroyModel();
   PretendPasswordWaiting();
-  EXPECT_FALSE(model_->ShouldShowGoogleSmartLockWelcome());
+
+  EXPECT_FALSE(model()->ShouldShowGoogleSmartLockWelcome());
   EXPECT_FALSE(prefs()->GetBoolean(
       password_manager::prefs::kWasSavePrompFirstRunExperienceShown));
 }
@@ -453,10 +441,8 @@
                                            test_case.experiment_group);
   }
 
-  EXPECT_CALL(*controller(), GetCurrentInteractionStats())
-      .WillOnce(Return(nullptr));
   PretendPasswordWaiting();
-  EXPECT_THAT(base::UTF16ToUTF8(model_->title()),
+  EXPECT_THAT(base::UTF16ToUTF8(model()->title()),
               testing::HasSubstr(test_case.expected_title));
 }
 
@@ -523,7 +509,7 @@
       break;
   }
 
-  model_->OnManageLinkClicked();
+  model()->OnManageLinkClicked();
 }
 
 namespace {
@@ -584,7 +570,7 @@
       break;
   }
 
-  model_->OnBrandLinkClicked();
+  model()->OnBrandLinkClicked();
 }
 
 namespace {
diff --git a/chrome/browser/ui/passwords/manage_passwords_test.h b/chrome/browser/ui/passwords/manage_passwords_test.h
index a314213..49112b1e 100644
--- a/chrome/browser/ui/passwords/manage_passwords_test.h
+++ b/chrome/browser/ui/passwords/manage_passwords_test.h
@@ -18,9 +18,8 @@
 class ManagePasswordsIconView;
 class PasswordsClientUIDelegate;
 
-// Test class for the various password management view bits and pieces. Sets
-// up a ManagePasswordsUIControllerMock, and provides some helper methods
-// to poke at the bubble, icon, and controller's state.
+// Test class for the various password management view bits and pieces. Provides
+// some helper methods to poke at the bubble, icon, and controller's state.
 class ManagePasswordsTest : public InProcessBrowserTest {
  public:
   ManagePasswordsTest();
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.cc
index 9c05be16..98e9d174 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.cc
@@ -12,99 +12,11 @@
 
 ManagePasswordsUIControllerMock::ManagePasswordsUIControllerMock(
     content::WebContents* contents)
-    : ManagePasswordsUIController(contents),
-      navigated_to_settings_page_(false),
-      saved_password_(false),
-      updated_password_(false),
-      never_saved_password_(false),
-      choose_credential_(false),
-      state_overridden_(false),
-      state_(password_manager::ui::INACTIVE_STATE),
-      password_manager_(&client_) {
+    : ManagePasswordsUIController(contents) {
   // Do not silently replace an existing ManagePasswordsUIController because it
   // unregisters itself in WebContentsDestroyed().
   EXPECT_FALSE(contents->GetUserData(UserDataKey()));
   contents->SetUserData(UserDataKey(), this);
-  set_client(&client_);
 }
 
-ManagePasswordsUIControllerMock::
-    ~ManagePasswordsUIControllerMock() {}
-
-void ManagePasswordsUIControllerMock::
-    NavigateToPasswordManagerSettingsPage() {
-  navigated_to_settings_page_ = true;
-}
-
-const autofill::PasswordForm&
-    ManagePasswordsUIControllerMock::GetPendingPassword() const {
-  return pending_password_;
-}
-
-void ManagePasswordsUIControllerMock::SetPendingPassword(
-    autofill::PasswordForm pending_password) {
-  pending_password_ = pending_password;
-}
-
-password_manager::ui::State ManagePasswordsUIControllerMock::GetState() const {
-  return state_overridden_ ? state_ : ManagePasswordsUIController::GetState();
-}
-
-void ManagePasswordsUIControllerMock::SetState(
-    password_manager::ui::State state) {
-  state_overridden_ = true;
-  state_ = state;
-}
-
-void ManagePasswordsUIControllerMock::UnsetState() {
-  state_overridden_ = false;
-}
-
-void ManagePasswordsUIControllerMock::UpdateBubbleAndIconVisibility() {
-  OnBubbleShown();
-}
-
-void ManagePasswordsUIControllerMock::
-    UpdateAndroidAccountChooserInfoBarVisibility() {
-  OnBubbleShown();
-}
-
-void ManagePasswordsUIControllerMock::OnBubbleHidden() {}
-
-void ManagePasswordsUIControllerMock::SavePassword() {
-  saved_password_ = true;
-}
-
-void ManagePasswordsUIControllerMock::UpdatePassword(
-    const autofill::PasswordForm& password_form) {
-  updated_password_ = true;
-}
-void ManagePasswordsUIControllerMock::NeverSavePassword() {
-  never_saved_password_ = true;
-}
-
-void ManagePasswordsUIControllerMock::ChooseCredential(
-    const autofill::PasswordForm& form,
-    password_manager::CredentialType form_type) {
-  EXPECT_FALSE(choose_credential_);
-  choose_credential_ = true;
-  chosen_credential_ = form;
-}
-
-password_manager::InteractionsStats*
-ManagePasswordsUIControllerMock::GetCurrentInteractionStats() const {
-  return nullptr;
-}
-
-void ManagePasswordsUIControllerMock::PretendSubmittedPassword(
-    ScopedVector<autofill::PasswordForm> best_matches) {
-  ASSERT_FALSE(best_matches.empty());
-  autofill::PasswordForm observed_form = *best_matches[0];
-  scoped_ptr<password_manager::PasswordFormManager> form_manager(
-      new password_manager::PasswordFormManager(&password_manager_, &client_,
-                                                driver_.AsWeakPtr(),
-                                                observed_form, true));
-  form_manager->SimulateFetchMatchingLoginsFromPasswordStore();
-  form_manager->OnGetPasswordStoreResults(best_matches.Pass());
-  OnPasswordSubmitted(form_manager.Pass());
-}
+ManagePasswordsUIControllerMock::~ManagePasswordsUIControllerMock() {}
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h
index 3d105458..3838ab2f 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h
@@ -5,102 +5,45 @@
 #ifndef CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_MOCK_H_
 #define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_MOCK_H_
 
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
-#include "components/password_manager/core/browser/password_manager.h"
-#include "components/password_manager/core/browser/stub_password_manager_client.h"
-#include "components/password_manager/core/browser/stub_password_manager_driver.h"
-#include "components/password_manager/core/common/password_manager_ui.h"
-#include "content/public/browser/navigation_details.h"
+#include "testing/gmock/include/gmock/gmock.h"
 
 namespace content {
 class WebContents;
 }  // namespace content
 
-namespace password_manager {
-class PasswordManager;
-class PasswordManagerClient;
-class PasswordManagerDriver;
-enum class CredentialType;
-}
-
-// This mock is used in tests to ensure that we're just testing the controller
-// behavior, and not the behavior of the bits and pieces it relies upon (like
-// FormManager).
-class ManagePasswordsUIControllerMock
-    : public ManagePasswordsUIController {
+class ManagePasswordsUIControllerMock : public ManagePasswordsUIController {
  public:
   explicit ManagePasswordsUIControllerMock(
       content::WebContents* contents);
   ~ManagePasswordsUIControllerMock() override;
 
-  // Navigation, surprisingly, is platform-specific; Android's settings page
-  // is native UI and therefore isn't available in a tab for unit tests.
-  //
-  // TODO(mkwst): Determine how to reasonably test this on that platform.
-  void NavigateToPasswordManagerSettingsPage() override;
-  bool navigated_to_settings_page() const {
-    return navigated_to_settings_page_;
-  }
-
-  // We don't have a FormManager in tests, so stub these out.
-  void SavePassword() override;
-  bool saved_password() const { return saved_password_; }
-
-  void UpdatePassword(const autofill::PasswordForm& password_form) override;
-  bool updated_password() const { return updated_password_; }
-
-  void NeverSavePassword() override;
-  bool never_saved_password() const { return never_saved_password_; }
-
-  void ChooseCredential(const autofill::PasswordForm& form,
-                        password_manager::CredentialType form_type) override;
-  bool choose_credential() const { return choose_credential_; }
-  autofill::PasswordForm chosen_credential() { return chosen_credential_; }
-
-  const autofill::PasswordForm& GetPendingPassword() const override;
-  void SetPendingPassword(autofill::PasswordForm pending_password);
-
-  password_manager::ui::State GetState() const override;
-  void SetState(password_manager::ui::State state);
-  void UnsetState();
-
-  void UpdateBubbleAndIconVisibility() override;
-
-  void UpdateAndroidAccountChooserInfoBarVisibility() override;
-
-  void OnBubbleHidden() override;
-
-  password_manager::InteractionsStats* GetCurrentInteractionStats()
-      const override;
-
-  // Simulate the pending password state. |best_matches| can't be empty.
-  void PretendSubmittedPassword(
-    ScopedVector<autofill::PasswordForm> best_matches);
-
-  static scoped_ptr<password_manager::PasswordFormManager> CreateFormManager(
-      password_manager::PasswordManagerClient* client,
-      const autofill::PasswordForm& observed_form,
-      ScopedVector<autofill::PasswordForm> best_matches);
+  MOCK_CONST_METHOD0(GetOrigin, const GURL&());
+  MOCK_CONST_METHOD0(GetState, password_manager::ui::State());
+  MOCK_CONST_METHOD0(GetPendingPassword, const autofill::PasswordForm&());
+  MOCK_CONST_METHOD0(IsPasswordOverridden, bool());
+  MOCK_CONST_METHOD0(GetCurrentForms,
+                     const std::vector<const autofill::PasswordForm*>&());
+  MOCK_CONST_METHOD0(GetFederatedForms,
+                     const std::vector<const autofill::PasswordForm*>&());
+  MOCK_CONST_METHOD0(GetCurrentInteractionStats,
+                     password_manager::InteractionsStats*());
+  MOCK_METHOD0(OnBubbleShown, void());
+  MOCK_METHOD0(OnBubbleHidden, void());
+  MOCK_METHOD0(OnNoInteractionOnUpdate, void());
+  MOCK_METHOD0(OnNopeUpdateClicked, void());
+  MOCK_METHOD0(NeverSavePassword, void());
+  MOCK_METHOD0(SavePassword, void());
+  MOCK_METHOD1(UpdatePassword, void(const autofill::PasswordForm&));
+  MOCK_METHOD2(ChooseCredential,
+               void(const autofill::PasswordForm&,
+                    password_manager::CredentialType));
+  MOCK_METHOD0(NavigateToExternalPasswordManager, void());
+  MOCK_METHOD0(NavigateToSmartLockPage, void());
+  MOCK_METHOD0(NavigateToSmartLockHelpPage, void());
+  MOCK_METHOD0(NavigateToPasswordManagerSettingsPage, void());
 
  private:
-  bool navigated_to_settings_page_;
-  bool saved_password_;
-  bool updated_password_;
-  bool never_saved_password_;
-  bool choose_credential_;
-  bool state_overridden_;
-  password_manager::ui::State state_;
-  base::TimeDelta elapsed_;
-
-  autofill::PasswordForm chosen_credential_;
-  autofill::PasswordForm pending_password_;
-
-  password_manager::StubPasswordManagerClient client_;
-  password_manager::StubPasswordManagerDriver driver_;
-  password_manager::PasswordManager password_manager_;
-
   DISALLOW_COPY_AND_ASSIGN(ManagePasswordsUIControllerMock);
 };
 
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 e70815d..8991d50 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -263,15 +263,14 @@
 TEST_F(ManagePasswordsUIControllerTest, PasswordSubmitted) {
   scoped_ptr<password_manager::PasswordFormManager> test_form_manager(
       CreateFormManager());
+  test_form_manager->ProvisionallySave(
+      test_local_form(),
+      password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
   controller()->OnPasswordSubmitted(test_form_manager.Pass());
   EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE,
             controller()->GetState());
   EXPECT_TRUE(controller()->opened_bubble());
-
-  // TODO(mkwst): This should be the value of test_local_form().origin, but
-  // it's being masked by the stub implementation of
-  // ManagePasswordsUIControllerMock::PendingCredentials.
-  EXPECT_EQ(GURL::EmptyGURL(), controller()->GetOrigin());
+  EXPECT_EQ(test_local_form().origin, controller()->GetOrigin());
 
   ExpectIconStateIs(password_manager::ui::PENDING_PASSWORD_STATE);
 }
@@ -408,12 +407,11 @@
 
   scoped_ptr<password_manager::PasswordFormManager> test_form_manager(
       CreateFormManager());
+  test_form_manager->ProvisionallySave(
+      test_local_form(),
+      password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
   controller()->OnPasswordSubmitted(test_form_manager.Pass());
   EXPECT_EQ(password_manager::ui::INACTIVE_STATE, controller()->GetState());
-
-  // TODO(mkwst): This should be the value of test_local_form().origin, but
-  // it's being masked by the stub implementation of
-  // ManagePasswordsUIControllerMock::PendingCredentials.
   EXPECT_EQ(GURL::EmptyGURL(), controller()->GetOrigin());
 
   ExpectIconStateIs(password_manager::ui::INACTIVE_STATE);
diff --git a/chrome/browser/ui/views/download/download_danger_prompt_views.cc b/chrome/browser/ui/views/download/download_danger_prompt_views.cc
index ef7bbfb..cef28d1 100644
--- a/chrome/browser/ui/views/download/download_danger_prompt_views.cc
+++ b/chrome/browser/ui/views/download/download_danger_prompt_views.cc
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/compiler_specific.h"
 #include "chrome/browser/download/download_danger_prompt.h"
+
+#include "base/compiler_specific.h"
 #include "chrome/browser/download/download_stats.h"
 #include "chrome/browser/extensions/api/experience_sampling_private/experience_sampling.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/constrained_window/constrained_window_views.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/download_danger_type.h"
 #include "content/public/browser/download_item.h"
@@ -21,6 +23,7 @@
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/dialog_client_view.h"
 #include "ui/views/window/dialog_delegate.h"
+#include "url/gurl.h"
 
 using extensions::ExperienceSamplingEvent;
 
@@ -333,6 +336,11 @@
   OnDone done = done_;
   done_.Reset();
   if (download_ != NULL) {
+    if (!download_->GetURL().is_empty() &&
+        !download_->GetBrowserContext()->IsOffTheRecord()) {
+      SendSafeBrowsingDownloadRecoveryReport(
+          action == DownloadDangerPrompt::ACCEPT, download_->GetURL());
+    }
     download_->RemoveObserver(this);
     download_ = NULL;
   }
diff --git a/chrome/browser/ui/webui/bookmarks_ui_browsertest.cc b/chrome/browser/ui/webui/bookmarks_ui_browsertest.cc
index 81afc7f..8560489 100644
--- a/chrome/browser/ui/webui/bookmarks_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/bookmarks_ui_browsertest.cc
@@ -20,11 +20,7 @@
 
   void SetUpOnMainThread() override {
     InProcessBrowserTest::SetUpOnMainThread();
-
-    // Re-enable accessibility checks when audit failures are resolved.
-    // AX_TEXT_01: http://crbug.com/559201
-    // AX_ARIA_08: http://crbug.com/559202
-    // EnableAccessibilityChecksForTestCase(true);
+    EnableAccessibilityChecksForTestCase(true);
   }
 
   void OpenBookmarksManager() {
diff --git a/chrome/browser/ui/webui/downloads_ui_browsertest.js b/chrome/browser/ui/webui/downloads_ui_browsertest.js
index 8ffba04..89fc311 100644
--- a/chrome/browser/ui/webui/downloads_ui_browsertest.js
+++ b/chrome/browser/ui/webui/downloads_ui_browsertest.js
@@ -120,8 +120,6 @@
   setUp: function() {
     // Doesn't create any fake downloads.
     assertEquals(0, downloads.Manager.size());
-
-    this.updateAccessibilityAuditConfig();
   },
 };
 
diff --git a/chrome/browser/ui/webui/downloads_ui_browsertest_base.js b/chrome/browser/ui/webui/downloads_ui_browsertest_base.js
index 24ec279..4af9e7e 100644
--- a/chrome/browser/ui/webui/downloads_ui_browsertest_base.js
+++ b/chrome/browser/ui/webui/downloads_ui_browsertest_base.js
@@ -47,8 +47,6 @@
    * @override
    */
   setUp: function() {
-    testing.Test.prototype.setUp.call(this);
-
     this.createdDownloads = [];
 
     // The entries will begin at 1:00 AM on Sept 2, 2008, and will be spaced
@@ -60,26 +58,6 @@
     }
     downloads.Manager.updateAll(this.createdDownloads);
     expectEquals(downloads.Manager.size(), TOTAL_RESULT_COUNT);
-
-    this.updateAccessibilityAuditConfig();
-  },
-
-  /**
-   * Disables failing accessibility audits. This should be removed when all
-   * audit issues have been resolved.
-   */
-  updateAccessibilityAuditConfig: function() {
-    // Enable when failure is resolved.
-    // AX_TEXT_01: http://crbug.com/559217
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'controlsWithoutLabel',
-        '#term');
-
-    // Enable when failure is resolved.
-    // AX_FOCUS_03: http://crbug.com/559219
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'tabIndexGreaterThanZero',
-        '#term');
   },
 
   /**
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js
index 1aca91b..d7847ef 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js
+++ b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js
@@ -51,14 +51,7 @@
 
   /** @override */
   setUp: function() {
-    testing.Test.prototype.setUp.call(this);
     testing.Test.disableAnimationsAndTransitions();
-
-    // Enable when failure is resolved.
-    // AX_ARIA_08: http://crbug.com/560903
-    this.accessibilityAuditConfig.ignoreSelectors(
-      'requiredOwnedAriaRoleMissing',
-      '#kiosk-app-list');
   },
 
   /**
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc
index 0ecb0dc..60990ff7 100644
--- a/chrome/browser/ui/webui/options/content_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/content_settings_handler.cc
@@ -29,6 +29,7 @@
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
+#include "chrome/common/features.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
@@ -451,7 +452,7 @@
     {"cookiesShowCookies", IDS_COOKIES_SHOW_COOKIES_BUTTON},
     {"flashStorageSettings", IDS_FLASH_STORAGE_SETTINGS},
     {"flashStorageUrl", IDS_FLASH_STORAGE_URL},
-#if defined(ENABLE_GOOGLE_NOW)
+#if BUILDFLAG(ENABLE_GOOGLE_NOW)
     {"googleGeolocationAccessEnable",
      IDS_GEOLOCATION_GOOGLE_ACCESS_ENABLE_CHKBOX},
 #endif
diff --git a/chrome/browser/ui/webui/options/language_options_browsertest.js b/chrome/browser/ui/webui/options/language_options_browsertest.js
index bfd3acb6..fc5ffba 100644
--- a/chrome/browser/ui/webui/options/language_options_browsertest.js
+++ b/chrome/browser/ui/webui/options/language_options_browsertest.js
@@ -16,23 +16,6 @@
 
   /** @override */
   browsePreload: 'chrome://settings-frame/languages',
-
-  /** @override */
-  setUp: function() {
-    OptionsBrowsertestBase.prototype.setUp.call(this);
-
-    // Enable when failure is resolved.
-    // AX_ARIA_10: http://crbug.com/559266
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'unsupportedAriaAttribute',
-        '#language-options-list');
-
-    // Enable when failure is resolved.
-    // AX_TEXT_04: http://crbug.com/559271
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'linkWithUnclearPurpose',
-        '#languagePage > .content-area > .language-options-header > A');
-  }
 };
 
 // Test opening language options has correct location.
diff --git a/chrome/browser/ui/webui/options/multilanguage_options_webui_browsertest.js b/chrome/browser/ui/webui/options/multilanguage_options_webui_browsertest.js
index deeff84..56419fa4 100644
--- a/chrome/browser/ui/webui/options/multilanguage_options_webui_browsertest.js
+++ b/chrome/browser/ui/webui/options/multilanguage_options_webui_browsertest.js
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-GEN_INCLUDE(['options_browsertest_base.js']);
 GEN('#include "chrome/browser/ui/webui/options/' +
     'multilanguage_options_browsertest.h"');
 
@@ -14,7 +13,7 @@
 function MultilanguageOptionsWebUIBrowserTest() {}
 
 MultilanguageOptionsWebUIBrowserTest.prototype = {
-  __proto__: OptionsBrowsertestBase.prototype,
+  __proto__: testing.Test.prototype,
 
   /** @override */
   browsePreload: 'chrome://settings-frame/languages',
@@ -33,7 +32,7 @@
 
   /** @override */
   setUp: function() {
-    OptionsBrowsertestBase.prototype.setUp.call(this);
+    testing.Test.prototype.setUp.call(this);
 
     assertTrue(loadTimeData.getBoolean('enableMultilingualSpellChecker'));
     assertFalse(cr.isMac);
@@ -41,29 +40,6 @@
     expectFalse($('edit-custom-dictionary-button').hidden);
     this.expectEnableSpellcheckCheckboxHidden();
     this.expectCurrentlySelected('fr');
-
-    var requiredOwnedAriaRoleMissingSelectors = [
-      '#default-search-engine-list',
-      '#other-search-engine-list',
-    ];
-
-    // Enable when failure is resolved.
-    // AX_ARIA_08: http://crbug.com/559320
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'requiredOwnedAriaRoleMissing',
-        requiredOwnedAriaRoleMissingSelectors);
-
-    // Enable when failure is resolved.
-    // AX_ARIA_10: http://crbug.com/559266
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'unsupportedAriaAttribute',
-        '#language-options-list');
-
-    // Enable when failure is resolved.
-    // AX_TEXT_04: http://crbug.com/559271
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'linkWithUnclearPurpose',
-        '#languagePage > .content-area > .language-options-header > A');
   },
 
   /** @override */
@@ -164,7 +140,7 @@
 
   /** @override */
   setUp: function() {
-    OptionsBrowsertestBase.prototype.setUp.call(this);
+    testing.Test.prototype.setUp.call(this);
 
     assertTrue(loadTimeData.getBoolean('enableMultilingualSpellChecker'));
     assertFalse(cr.isMac);
@@ -173,18 +149,6 @@
     this.expectEnableSpellcheckCheckboxHidden();
     this.expectCurrentlySelected('');
     this.expectRegisteredDictionariesPref('');
-
-    // Enable when failure is resolved.
-    // AX_ARIA_10: http://crbug.com/559266
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'unsupportedAriaAttribute',
-        '#language-options-list');
-
-    // Enable when failure is resolved.
-    // AX_TEXT_04: http://crbug.com/559271
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'linkWithUnclearPurpose',
-        '#languagePage > .content-area > .language-options-header > A');
   },
 };
 
diff --git a/chrome/browser/ui/webui/options/options_browsertest.js b/chrome/browser/ui/webui/options/options_browsertest.js
index 4de8c19..895928a 100644
--- a/chrome/browser/ui/webui/options/options_browsertest.js
+++ b/chrome/browser/ui/webui/options/options_browsertest.js
@@ -79,31 +79,6 @@
     this.mockHandler.stubs().observePrefs(ANYTHING);
     this.mockHandler.stubs().coreOptionsUserMetricsAction(ANYTHING);
   },
-
-  /** @override */
-  setUp: function() {
-    OptionsBrowsertestBase.prototype.setUp.call(this);
-
-    // Enable when failure is resolved.
-    // AX_ARIA_10: http://crbug.com/559329
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'unsupportedAriaAttribute',
-        '#profiles-list');
-
-    var linkWithUnclearPurposeSelectors = [
-      '#sync-overview > A',
-      '#privacy-explanation > A',
-      '#languages-section > .settings-row > A',
-      '#cloudprint-options-mdns > .settings-row > A',
-      '#do-not-track-confirm-overlay > .action-area > .hbox.stretch > A',
-    ];
-
-    // Enable when failure is resolved.
-    // AX_TEXT_04: http://crbug.com/559318
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'linkWithUnclearPurpose',
-        linkWithUnclearPurposeSelectors);
-  },
 };
 
 /**
@@ -403,44 +378,6 @@
   /** @override */
   typedefCppFixture: 'OptionsBrowserTest',
 
-  /** @override */
-  setUp: function() {
-    OptionsWebUITest.prototype.setUp.call(this);
-
-    // Enable when failure is resolved.
-    // AX_ARIA_10: http://crbug.com/559329
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'unsupportedAriaAttribute',
-        '#profiles-list');
-
-    var controlsWithoutLabelSelectors = [
-      '#cookies-view-page > .content-area.cookies-list-content-area > *',
-      '#other-search-engine-list > .deletable-item > DIV > *',
-    ];
-
-    // Enable when failure is resolved.
-    // AX_TEXT_01: http://crbug.com/559330
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'controlsWithoutLabel',
-        controlsWithoutLabelSelectors);
-
-    var linkWithUnclearPurposeSelectors = [
-      '#sync-overview > A',
-      '#privacy-explanation > A',
-      '#languages-section > .settings-row > A',
-      '#cloudprint-options-mdns > .settings-row > A',
-      // Selectors below only affect ChromeOS tests.
-      '#privacy-section > DIV > DIV:nth-of-type(9) > A',
-      '#accessibility-learn-more',
-    ];
-
-    // Enable when failure is resolved.
-    // AX_TEXT_04: http://crbug.com/559326
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'linkWithUnclearPurpose',
-        linkWithUnclearPurposeSelectors);
-  },
-
   testGenPreamble: function() {
     // Start with no supervised users managed by this profile.
     GEN('  ClearPref("' + SUPERVISED_USERS_PREF + '");');
diff --git a/chrome/browser/ui/webui/options/options_browsertest_base.js b/chrome/browser/ui/webui/options/options_browsertest_base.js
index e298ea1..1483ba32 100644
--- a/chrome/browser/ui/webui/options/options_browsertest_base.js
+++ b/chrome/browser/ui/webui/options/options_browsertest_base.js
@@ -16,54 +16,4 @@
 
   /** @override */
   accessibilityIssuesAreErrors: true,
-
-  /** @override */
-  setUp: function() {
-    testing.Test.prototype.setUp.call(this);
-
-    var requiredOwnedAriaRoleMissingSelectors = [
-      '#address-list',
-      '#creditcard-list',
-      '#home-page-overlay > .autocomplete-suggestions',
-      '#language-options-list',
-      '#manage-profile-icon-grid',
-      '#create-profile-icon-grid',
-      '#saved-passwords-list',
-      '#password-exceptions-list',
-      '#extension-keyword-list',
-      '#startup-overlay > .autocomplete-suggestions',
-      '#content-settings-exceptions-area > .content-area > *',
-      '#cookies-list',
-      '#handlers-list',
-      '#ignored-handlers-list',
-      '#supervised-user-list',
-      '#select-avatar-grid',
-      '#language-dictionary-overlay-word-list',
-      // Selectors below only affect ChromeOS tests.
-      '#bluetooth-unpaired-devices-list',
-      '#ignored-host-list',
-      '#remembered-network-list',
-      '#bluetooth-paired-devices-list',
-    ];
-
-    // Enable when failure is resolved.
-    // AX_ARIA_08: http://crbug.com/559265
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'requiredOwnedAriaRoleMissing',
-        requiredOwnedAriaRoleMissingSelectors);
-
-    var tabIndexGreaterThanZeroSelectors = [
-      '#user-image-grid',
-      '#discard-photo',
-      '#take-photo',
-      '#flip-photo',
-      '#change-picture-overlay-confirm',
-    ];
-
-    // Enable when failure is resolved.
-    // AX_FOCUS_03: http://crbug.com/560910
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'tabIndexGreaterThanZero',
-        tabIndexGreaterThanZeroSelectors);
-  },
 };
diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc
index e69c199..56e784c2 100644
--- a/chrome/browser/ui/webui/options/options_ui.cc
+++ b/chrome/browser/ui/webui/options/options_ui.cc
@@ -47,6 +47,7 @@
 #include "chrome/browser/ui/webui/options/startup_pages_handler.h"
 #include "chrome/browser/ui/webui/options/sync_setup_handler.h"
 #include "chrome/browser/ui/webui/theme_source.h"
+#include "chrome/common/features.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/locale_settings.h"
@@ -100,7 +101,7 @@
 #include "chrome/browser/ui/webui/options/certificate_manager_handler.h"
 #endif
 
-#if defined(ENABLE_GOOGLE_NOW)
+#if BUILDFLAG(ENABLE_GOOGLE_NOW)
 #include "chrome/browser/ui/webui/options/geolocation_options_handler.h"
 #endif
 
@@ -279,7 +280,7 @@
   AddOptionsPageUIHandler(localized_strings, new CreateProfileHandler());
   AddOptionsPageUIHandler(localized_strings, new EasyUnlockHandler());
   AddOptionsPageUIHandler(localized_strings, new FontSettingsHandler());
-#if defined(ENABLE_GOOGLE_NOW)
+#if BUILDFLAG(ENABLE_GOOGLE_NOW)
   AddOptionsPageUIHandler(localized_strings, new GeolocationOptionsHandler());
 #endif
   AddOptionsPageUIHandler(localized_strings, new options::HelpOverlayHandler());
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index cfd46cc..9495002 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -104,6 +104,7 @@
     'chrome_browser_ui.gypi',
     'chrome_common.gypi',
     'chrome_installer_util.gypi',
+    'chrome_features.gypi',
   ],
   'conditions': [
     ['OS!="ios"', {
diff --git a/chrome/chrome_android.gypi b/chrome/chrome_android.gypi
index 9c8b394..1f1d797f 100644
--- a/chrome/chrome_android.gypi
+++ b/chrome/chrome_android.gypi
@@ -14,6 +14,7 @@
         'chrome.gyp:browser',
         'chrome.gyp:browser_ui',
         'chrome.gyp:child',
+        'chrome_features.gyp:chrome_common_features',
         'chrome.gyp:plugin',
         'chrome.gyp:renderer',
         'chrome.gyp:utility',
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index cba3bcc..d6df1df0 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -3066,6 +3066,7 @@
         # NOTE: New dependencies should generally be added in the OS!="ios"
         # dependencies block below, rather than here.
         'browser_ui',
+        'chrome_features.gyp:chrome_common_features',
         'chrome_resources.gyp:chrome_extra_resources',
         'chrome_resources.gyp:chrome_resources',
         'chrome_resources.gyp:chrome_strings',
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index 8c0ca4fa..9871077 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -956,6 +956,7 @@
       # browser, then we can clean up these dependencies.
       'dependencies': [
         'browser/extensions/api/api_registration.gyp:chrome_api_registration',
+        'chrome_features.gyp:chrome_common_features',
         'chrome_resources.gyp:chrome_extra_resources',
         'chrome_resources.gyp:chrome_resources',
         'chrome_resources.gyp:chrome_strings',
diff --git a/chrome/chrome_child.gypi b/chrome/chrome_child.gypi
index 6464a39..645dd5a 100644
--- a/chrome/chrome_child.gypi
+++ b/chrome/chrome_child.gypi
@@ -11,6 +11,7 @@
       'dependencies': [
         '../base/base.gyp:base',
         '../content/content.gyp:content_child',
+        'chrome_features.gyp:chrome_common_features',
       ],
       'include_dirs': [
         '..',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 1438853..d26010f 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -297,6 +297,7 @@
       # GN: //chrome/common:common
       'target_name': 'common',
       'type': 'static_library',
+      'hard_dependency': 1,  # Because of transitive dep on version_header.
       'variables': {
         'chrome_common_target': 1,
         'enable_wexit_time_destructors': 1,
@@ -320,6 +321,7 @@
         '<(DEPTH)/base/base.gyp:base_i18n',
         '<(DEPTH)/base/base.gyp:base_prefs',
         '<(DEPTH)/base/base.gyp:base_static',
+        '<(DEPTH)/chrome/chrome_features.gyp:chrome_common_features',
         '<(DEPTH)/chrome/chrome_resources.gyp:chrome_resources',
         '<(DEPTH)/chrome/chrome_resources.gyp:chrome_strings',
         '<(DEPTH)/chrome/chrome_resources.gyp:theme_resources',
@@ -565,6 +567,7 @@
       ],
       'dependencies': [
         '<(DEPTH)/base/base.gyp:base',
+        '<(DEPTH)/chrome/chrome_features.gyp:chrome_common_features',
         '<(DEPTH)/chrome/chrome_resources.gyp:chrome_resources',
         '<(DEPTH)/chrome/chrome_resources.gyp:chrome_strings',
         '<(DEPTH)/components/url_formatter/url_formatter.gyp:url_formatter',
diff --git a/chrome/chrome_debugger.gypi b/chrome/chrome_debugger.gypi
index 31991c6d..aefbb4d 100644
--- a/chrome/chrome_debugger.gypi
+++ b/chrome/chrome_debugger.gypi
@@ -15,6 +15,7 @@
         '../net/net.gyp:net',
         'browser/devtools/webrtc_device_provider_resources.gyp:webrtc_device_provider_resources',
         'browser/devtools/devtools_protocol_constants.gyp:devtools_protocol_constants',
+        'chrome_features.gyp:chrome_common_features',
       ],
       'include_dirs': [
         '..',
diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi
index f593901..a2fa6432 100644
--- a/chrome/chrome_exe.gypi
+++ b/chrome/chrome_exe.gypi
@@ -46,7 +46,10 @@
       # GN version: //chrome:chrome_initial
       'target_name': 'chrome_initial',
       'type': 'executable',
-      'dependencies' : [ '../chrome/common_constants.gyp:version_header', ],
+      'dependencies' : [
+        '../chrome/common_constants.gyp:version_header',
+        '../chrome/chrome_features.gyp:chrome_common_features',
+      ],
       # Name the exe chrome.exe, not chrome_initial.exe.
       'product_name': 'chrome',
       'mac_bundle': 1,
diff --git a/chrome/chrome_features.gyp b/chrome/chrome_features.gyp
new file mode 100644
index 0000000..0d29f18
--- /dev/null
+++ b/chrome/chrome_features.gyp
@@ -0,0 +1,22 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'includes': [
+    'chrome_features.gypi',
+  ],
+  'targets': [
+    {
+      # GN version: //chrome/common:features
+      'target_name': 'chrome_common_features',
+      'includes': [ '../build/buildflag_header.gypi' ],
+      'variables': {
+        'buildflag_header_path': 'chrome/common/features.h',
+        'buildflag_flags': [
+          'ENABLE_GOOGLE_NOW=<(enable_google_now)',
+        ],
+      },
+    },
+  ]
+}
diff --git a/chrome/chrome_features.gypi b/chrome/chrome_features.gypi
new file mode 100644
index 0000000..a4d8756
--- /dev/null
+++ b/chrome/chrome_features.gypi
@@ -0,0 +1,31 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+ 
+# This is the GYP equivalent of //chrome/common/features.gni.
+# Please keep in sync!
+
+{
+  'variables': {
+    'variables': {
+      # Conditional variables.
+      'conditions': [
+        ['OS=="android" or OS=="ios"', {
+          'enable_google_now%': 0,
+        }, {
+          'enable_google_now%': 1,
+        }]
+      ],
+    },
+
+    # Anything in the conditions needs to be copied to the outer scope to be
+    # accessible.
+    'enable_google_now%': '<(enable_google_now)',
+
+    # Grit defines based on the feature flags. These must be manually added to
+    # grit targets.
+    'chrome_grit_defines': [
+      '-D', 'enable_google_now=<(enable_google_now)',
+    ]
+  },
+}
diff --git a/chrome/chrome_plugin.gypi b/chrome/chrome_plugin.gypi
index 718666c..1cf98f8 100644
--- a/chrome/chrome_plugin.gypi
+++ b/chrome/chrome_plugin.gypi
@@ -12,6 +12,7 @@
         '../base/base.gyp:base',
         '../content/content.gyp:content_plugin',
         '../gin/gin.gyp:gin',
+        'chrome_features.gyp:chrome_common_features',
         'chrome_resources.gyp:chrome_strings',
       ],
       'include_dirs': [
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index b12ac525..40f12959 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -239,6 +239,7 @@
       'dependencies': [
         'common',
         'common_mojo_bindings',
+        'chrome_features.gyp:chrome_common_features',
         'chrome_resources.gyp:chrome_resources',
         'chrome_resources.gyp:chrome_strings',
         '../third_party/re2/re2.gyp:re2',
diff --git a/chrome/chrome_resources.gyp b/chrome/chrome_resources.gyp
index 6edb8194..85116d4 100644
--- a/chrome/chrome_resources.gyp
+++ b/chrome/chrome_resources.gyp
@@ -2,8 +2,14 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 {
+  'includes': [
+    'chrome_features.gypi',
+  ],
   'variables': {
+    # Apply Chrome-specific grit settings to all grit actions in this file.
     'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/chrome',
+    'grit_additional_defines': [ '<@(chrome_grit_defines)' ],
+
     'additional_modules_list_file': '<(SHARED_INTERMEDIATE_DIR)/chrome/browser/internal/additional_modules_list.txt',
   },
   'targets': [
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 28cbfb0..19ecd3b 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1617,6 +1617,7 @@
       'type': 'executable',
       'dependencies': [
         'browser',
+        'chrome_features.gyp:chrome_common_features',
         'chrome_resources.gyp:chrome_resources',
         'chrome_resources.gyp:chrome_strings',
         'chrome_resources.gyp:packed_extra_resources',
@@ -2111,6 +2112,7 @@
       'type': 'executable',
       'dependencies': [
         'browser',
+        'chrome_features.gyp:chrome_common_features',
         'chrome_resources.gyp:browser_tests_pak',
         'chrome_resources.gyp:chrome_resources',
         'chrome_resources.gyp:chrome_strings',
@@ -2655,6 +2657,7 @@
       'type': 'executable',
       'dependencies': [
         'browser',
+        'chrome_features.gyp:chrome_common_features',
         'chrome_resources.gyp:chrome_resources',
         'chrome_resources.gyp:chrome_strings',
         'chrome_resources.gyp:packed_extra_resources',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 1dc2c8c..efa77982 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1658,6 +1658,7 @@
         # NOTE: New dependencies should generally be added in the OS!="ios"
         # dependencies block below, rather than here.
         'browser',
+        'chrome_features.gyp:chrome_common_features',
         'chrome_resources.gyp:chrome_resources',
         'chrome_resources.gyp:chrome_strings',
         'chrome_resources.gyp:theme_resources',
@@ -2212,6 +2213,7 @@
         '../ui/base/ui_base.gyp:ui_base_test_support',
         '../ui/gfx/gfx.gyp:gfx_test_support',
         '../ui/resources/ui_resources.gyp:ui_resources',
+        'chrome_features.gyp:chrome_common_features',
         'chrome_resources.gyp:chrome_resources',
         'chrome_resources.gyp:chrome_strings',
       ],
diff --git a/chrome/chrome_utility.gypi b/chrome/chrome_utility.gypi
index d70f335..fb2f15d 100644
--- a/chrome/chrome_utility.gypi
+++ b/chrome/chrome_utility.gypi
@@ -124,6 +124,7 @@
         '../media/media.gyp:media',
         '../skia/skia.gyp:skia',
         '../third_party/libxml/libxml.gyp:libxml',
+        '<(DEPTH)/chrome/chrome_features.gyp:chrome_common_features',
         '<(DEPTH)/chrome/chrome_resources.gyp:chrome_resources',
         '<(DEPTH)/chrome/chrome_resources.gyp:chrome_strings',
         'common',
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index 0e8b0543..d0cbe2a4 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/buildflag_header.gni")
+import("//chrome/common/features.gni")
 import("//chrome/version.gni")
 import("//mojo/public/tools/bindings/mojom.gni")
 import("//tools/grit/grit_rule.gni")
@@ -36,6 +38,11 @@
   }
 }
 
+buildflag_header("features") {
+  header = "features.h"
+  flags = [ "ENABLE_GOOGLE_NOW=$enable_google_now" ]
+}
+
 # GYP version: chrome/chrome_common.gypi:common
 static_library("common") {
   sources = rebase_path(gypi_values.chrome_common_sources, ".", "//chrome")
@@ -47,6 +54,7 @@
   ]
 
   public_deps = [
+    ":features",
     "//base:base",
     "//base:base_static",
     "//base:i18n",
@@ -316,6 +324,7 @@
     "//content/public/common:result_codes",
   ]
   deps = [
+    ":features",
     ":version_header",
     "//base",
     "//base/third_party/dynamic_annotations",
diff --git a/chrome/common/extensions/api/file_system_provider.idl b/chrome/common/extensions/api/file_system_provider.idl
index b6ab86d..b18d46af 100644
--- a/chrome/common/extensions/api/file_system_provider.idl
+++ b/chrome/common/extensions/api/file_system_provider.idl
@@ -54,21 +54,24 @@
 
   // Represents metadata of a file or a directory.
   dictionary EntryMetadata {
-    // True if it is a directory.
-    boolean isDirectory;
+    // True if it is a directory. Must be provided if requested in
+    // <code>options</code>.
+    boolean? isDirectory;
 
     // Name of this entry (not full path name). Must not contain '/'. For root
-    // it must be empty.
-    DOMString name;
+    // it must be empty. Must be provided if requested in <code>options</code>.
+    DOMString? name;
 
-    // File size in bytes. Required for <code>OnGetMetadataRequested</code>.
+    // File size in bytes. Must be provided if requested in
+    // <code>options</code>.
     double? size;
 
-    // The last modified time of this entry. Required for
-    // <code>OnGetMetadataRequested</code>.
+    // The last modified time of this entry. Must be provided if requested in
+    // <code>options</code>.
     [instanceOf=Date] object? modificationTime;
 
-    // Mime type for the entry.
+    // Mime type for the entry. Always optional, but should be provided if
+    // requested in <code>options</code>.
     DOMString? mimeType;
 
     // Thumbnail image as a data URI in either PNG, JPEG or WEBP format, at most
@@ -177,6 +180,22 @@
     // The path of the entry to fetch metadata about.
     DOMString entryPath;
 
+    // Set to <code>true</code> if <code>is_directory</code> value is requested.
+    boolean isDirectory;
+
+    // Set to <code>true</code> if <code>name</code> value is requested.
+    boolean name;
+
+    // Set to <code>true</code> if <code>size</code> value is requested.
+    boolean size;
+
+    // Set to <code>true</code> if <code>modificationTime</code> value is
+    // requested.
+    boolean modificationTime;
+
+    // Set to <code>true</code> if <code>mimeType</code> value is requested.
+    boolean mimeType;
+
     // Set to <code>true</code> if the thumbnail is requested.
     boolean thumbnail;
   };
@@ -203,6 +222,25 @@
 
     // The path of the directory which contents are requested. 
     DOMString directoryPath;
+
+    // Set to <code>true</code> if <code>is_directory</code> value is requested.
+    boolean isDirectory;
+
+    // Set to <code>true</code> if <code>name</code> value is requested.
+    boolean name;
+
+    // Set to <code>true</code> if <code>size</code> value is requested.
+    boolean size;
+
+    // Set to <code>true</code> if <code>modificationTime</code> value is
+    // requested.
+    boolean modificationTime;
+
+    // Set to <code>true</code> if <code>mimeType</code> value is requested.
+    boolean mimeType;
+
+    // Set to <code>true</code> if the thumbnail is requested.
+    boolean thumbnail;
   };
 
   // Options for the $(ref:onOpenFileRequested) event.
diff --git a/chrome/common/features.gni b/chrome/common/features.gni
new file mode 100644
index 0000000..2e92745c
--- /dev/null
+++ b/chrome/common/features.gni
@@ -0,0 +1,12 @@
+# 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.
+
+# This is the GN version of //chrome/chrome_features.gypi.
+# Please keep in sync!
+
+declare_args() {
+  enable_google_now = !is_ios && !is_android
+}
+
+chrome_grit_defines = [ "enable_google_now=$enable_google_now" ]
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index f3bfd8e..d546cb0 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -5,6 +5,7 @@
 #include "chrome/common/pref_names.h"
 
 #include "base/basictypes.h"
+#include "chrome/common/features.h"
 #include "chrome/common/pref_font_webkit_names.h"
 
 namespace prefs {
@@ -1557,7 +1558,7 @@
 const char kGeolocationEnabled[] = "geolocation.enabled";
 #endif
 
-#if defined(ENABLE_GOOGLE_NOW)
+#if BUILDFLAG(ENABLE_GOOGLE_NOW)
 // Boolean that is true when Google services can use the user's location.
 const char kGoogleGeolocationAccessEnabled[] =
     "googlegeolocationaccess.enabled";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index f82326b4..79e1d12a 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -10,6 +10,7 @@
 #include <stddef.h>
 
 #include "build/build_config.h"
+#include "chrome/common/features.h"
 
 namespace prefs {
 
@@ -557,7 +558,7 @@
 extern const char kGeolocationEnabled[];
 #endif
 
-#if defined(ENABLE_GOOGLE_NOW)
+#if BUILDFLAG(ENABLE_GOOGLE_NOW)
 extern const char kGoogleGeolocationAccessEnabled[];
 #endif
 extern const char kGoogleNowLauncherEnabled[];
diff --git a/chrome/common_constants.gyp b/chrome/common_constants.gyp
index 134878e..a8d701f 100644
--- a/chrome/common_constants.gyp
+++ b/chrome/common_constants.gyp
@@ -72,6 +72,7 @@
       # GN version: //chrome/common:constants
       'target_name': 'common_constants',
       'type': 'static_library',
+      'hard_dependency': 1,  # Because of transitive dep on version_header.
       'sources': [
         '<@(common_constants_sources)'
       ],
@@ -80,6 +81,7 @@
       ],
       'dependencies': [
         'version_header',
+        'chrome_features.gyp:chrome_common_features',
         '../base/base.gyp:base',
         '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
         '../components/components.gyp:bookmarks_common',
@@ -108,6 +110,7 @@
       'targets': [
         {
           'target_name': 'common_constants_win64',
+          'hard_dependency': 1,  # Because of transitive dep on version_header.
           'type': 'static_library',
           'sources': [
             '<@(common_constants_sources)'
@@ -117,6 +120,7 @@
           ],
           'dependencies': [
             'version_header',
+            'chrome_features.gyp:chrome_common_features',
             '../base/base.gyp:base_win64',
             '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations_win64',
             '../components/nacl.gyp:nacl_switches_win64',
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc
index 76873331..bc7a762 100644
--- a/chrome/renderer/autofill/form_autofill_browsertest.cc
+++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -13,7 +13,6 @@
 #include "components/autofill/content/renderer/form_cache.h"
 #include "components/autofill/core/common/autofill_data_validation.h"
 #include "components/autofill/core/common/form_data.h"
-#include "components/autofill/core/common/web_element_descriptor.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebVector.h"
@@ -56,6 +55,20 @@
                                      // or Preview.
 };
 
+struct WebElementDescriptor {
+  enum RetrievalMethod {
+    CSS_SELECTOR,
+    ID,
+    NONE,
+  };
+
+  // Information to retrieve element with.
+  std::string descriptor;
+
+  // Which retrieval method to use.
+  RetrievalMethod retrieval_method = NONE;
+};
+
 const char kFormHtml[] =
     "<FORM name='TestForm' action='http://buh.com' method='post'>"
     "  <INPUT type='text' id='firstname'/>"
diff --git a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
index b43a9d7..59c43e54 100644
--- a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
@@ -51,16 +51,86 @@
 }
 
 /**
+ * Verifies if the passed metadata is valid.
+ * @param {!GetMetadataOptions|!ReadDirectoryOptions} options
+ * @return {boolean} True if valid, false if invalid.
+ */
+function verifyMetadata(options, metadata) {
+  // Ideally we'd like to consider the following as errors, but for backward
+  // compatibility they are warnings only.
+  if (!options.isDirectory && metadata.isDirectory !== undefined)
+    console.warn('IsDirectory specified, but not requested.');
+  if (!options.name && metadata.name !== undefined)
+    console.warn('Name specified, but not requested.');
+  if (!options.size && metadata.size !== undefined)
+    console.warn('Size specified, but not requested.');
+  if (!options.modificationTime && metadata.modificationTime !== undefined)
+    console.warn('Last modification time specified, but not requested.');
+  if (!options.mimeType && metadata.mimeType !== undefined) {
+    console.warn('MIME type specified, but not requested.');
+  } else {
+    if (metadata.mimeType === '') {
+      warning = 'MIME type must not be an empty string.' +
+          'If unknown, then do not set it.';
+    }
+  }
+
+  if (options.isDirectory && metadata.isDirectory === undefined) {
+    console.error('IsDirectory is required for this request.');
+    return false;
+  }
+
+  if (options.name && metadata.name === undefined) {
+    console.error('Name is required for this request.');
+    return false;
+  }
+
+  if (options.size && metadata.size === undefined) {
+    console.error('Size is required for this request.');
+    return false;
+  }
+
+  if (options.modificationTime && metadata.modificationTime === undefined) {
+    console.error('Last modification time is required for this request.');
+    return false;
+  }
+
+  // It is invalid to return a thumbnail when it's not requested. The
+  // restriction is added in order to avoid fetching the thumbnail while
+  // it's not needed.
+  if (!options.thumbnail && metadata.thumbnail !== undefined) {
+    console.error('Thumbnail data provided, but not requested.');
+    return false;
+  }
+
+  // Check the format and size. Note, that in the C++ layer, there is
+  // another sanity check to avoid passing any evil URL.
+  if (metadata.thumbnail !== undefined && !verifyImageURI(metadata.thumbnail)) {
+    console.error('Thumbnail format invalid.');
+    return false;
+  }
+
+  if (metadata.thumbnail !== undefined &&
+      metadata.thumbnail.length > METADATA_THUMBNAIL_SIZE_LIMIT) {
+    console.error('Thumbnail data too large.');
+    return false;
+  }
+
+  return true;
+}
+
+/**
  * Annotates an entry metadata by serializing its modifiedTime value.
  * @param {EntryMetadata} metadata Input metadata.
  * @return {EntryMetadata} metadata Annotated metadata, which can be passed
  *     back to the C++ layer.
  */
 function annotateMetadata(metadata) {
-  var result = {
-    isDirectory: metadata.isDirectory,
-    name: metadata.name,
-  };
+  var result = {};
+  if (metadata.isDirectory !== undefined)
+    result.isDirectory = metadata.isDirectory;
+  if (metadata.name !== undefined)
+    result.name = metadata.name;
   if (metadata.size !== undefined)
     result.size = metadata.size;
   if (metadata.modificationTime !== undefined)
@@ -103,32 +173,7 @@
       var executionStart = Date.now();
       var options = args[0];
       var onSuccessCallback = function(metadata) {
-        var error;
-        // TODO(mtomasz): Remove the following two fields once crbug.com/413161
-        // is landed.
-        if (options.size !== undefined)
-          error = 'Size is required for this event.';
-        if (options.modificationTime !== undefined)
-          error = 'Last modified time is required for this event.';
-
-        // It is invalid to return a thumbnail when it's not requested. The
-        // restriction is added in order to avoid fetching the thumbnail while
-        // it's not needed.
-        if (!options.thumbnail && metadata.thumbnail)
-          error = 'Thumbnail data provided, but not requested.';
-
-        // Check the format and size. Note, that in the C++ layer, there is
-        // another sanity check to avoid passing any evil URL.
-        if ('thumbnail' in metadata && !verifyImageURI(metadata.thumbnail))
-          error = 'Thumbnail format invalid.';
-
-        if ('thumbnail' in metadata &&
-            metadata.thumbnail.length > METADATA_THUMBNAIL_SIZE_LIMIT) {
-          error = 'Thumbnail data too large.';
-        }
-
-        if (error) {
-          console.error(error);
+        if (!verifyMetadata(options, metadata)) {
           fileSystemProviderInternal.operationRequestedError(
               options.fileSystemId, options.requestId, 'FAILED',
               Date.now() - executionStart);
@@ -179,25 +224,22 @@
       var executionStart = Date.now();
       var options = args[0];
       var onSuccessCallback = function(entries, hasNext) {
-        var annotatedEntries = entries.map(annotateMetadata);
-        // It is invalid to return a thumbnail when it's not requested.
-        var error;
-        annotatedEntries.forEach(function(metadata) {
-          if (metadata.thumbnail) {
-            var error =
-                'Thumbnails must not be provided when reading a directory.';
+        var error = false;
+        for (var i = 0; i < entries; i++) {
+          if (!validateMetadata(options, entries[i])) {
+            error = true;
             return;
           }
-        });
+        }
 
         if (error) {
-          console.error(error);
           fileSystemProviderInternal.operationRequestedError(
               options.fileSystemId, options.requestId, 'FAILED',
               Date.now() - executionStart);
           return;
         }
 
+        var annotatedEntries = entries.map(annotateMetadata);
         fileSystemProviderInternal.readDirectoryRequestedSuccess(
             options.fileSystemId, options.requestId, annotatedEntries, hasNext,
             Date.now() - executionStart);
diff --git a/chrome/test/data/chromeos/oobe_webui_browsertest.js b/chrome/test/data/chromeos/oobe_webui_browsertest.js
index c14bff61..e2c4ce57 100644
--- a/chrome/test/data/chromeos/oobe_webui_browsertest.js
+++ b/chrome/test/data/chromeos/oobe_webui_browsertest.js
@@ -57,62 +57,6 @@
     this.accessibilityAuditConfig.ignoreSelectors(
         'focusableElementNotVisibleAndNotAriaHidden',
         '#iconButton');
-
-    // Enable when failure is resolved.
-    // AX_ARIA_02: http://crbug.com/560932
-    this.accessibilityAuditConfig.ignoreSelectors(
-      'nonExistentAriaRelatedElement',
-      '#cancelConfirmDlg');
-
-    var requiredOwnedAriaRoleMissingSelectors = [
-      '#networks-list-dropdown-container',
-      '#offline-networks-list-dropdown-container',
-      '#supervised-user-creation-image-grid',
-      'body > .decorated',
-    ];
-
-    // Enable when failure is resolved.
-    // AX_ARIA_08: http://crbug.com/560924
-    this.accessibilityAuditConfig.ignoreSelectors(
-      'requiredOwnedAriaRoleMissing',
-      requiredOwnedAriaRoleMissingSelectors);
-
-    var badAriaAttributeSelectors = [
-      '#forgotPasswordDlg',
-      '#cancelConfirmDlg',
-    ];
-
-    // Enable when failure is resolved.
-    // AX_ARIA_11: http://crbug.com/560935
-    this.accessibilityAuditConfig.ignoreSelectors(
-      'badAriaAttribute',
-      badAriaAttributeSelectors);
-
-    var tabIndexGreaterThanZeroSelectors = [
-      '#user-image-grid',
-      '#discard-photo',
-      '#take-photo',
-      '#flip-photo',
-    ];
-
-    // Enable when failure is resolved.
-    // AX_FOCUS_03: http://crbug.com/560928
-    this.accessibilityAuditConfig.ignoreSelectors(
-      'tabIndexGreaterThanZero',
-      tabIndexGreaterThanZeroSelectors);
-
-    var controlsWithoutLabelSelectors = [
-      '#supervised-user-creation-managers-pane',
-      '#supervised-user-creation-name',
-      '#supervised-user-creation-password',
-      '#supervised-user-creation-password-confirm',
-    ];
-
-    // Enable when failure is resolved.
-    // AX_TEXT_01: http://crbug.com/560939
-    this.accessibilityAuditConfig.ignoreSelectors(
-      'controlsWithoutLabel',
-      controlsWithoutLabelSelectors);
   },
 };
 
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/get_metadata/test.js b/chrome/test/data/extensions/api_test/file_system_provider/get_metadata/test.js
index 680ac3d7..a7a57a9 100644
--- a/chrome/test/data/extensions/api_test/file_system_provider/get_metadata/test.js
+++ b/chrome/test/data/extensions/api_test/file_system_provider/get_metadata/test.js
@@ -38,6 +38,36 @@
 });
 
 /**
+ * @type {Object}
+ * @const
+ */
+var TESTING_ONLY_BASIC_FILE = Object.freeze({
+  isDirectory: false,
+  name: 'invalid-time.txt',
+});
+
+/**
+ * @type {string}
+ * @const
+ */
+var TESTING_ONLY_BASIC_FILE_NAME = 'basic.txt';
+
+/**
+ * @type {Object}
+ * @const
+ */
+var TESTING_ONLY_SIZE_FILE = Object.freeze({
+  isDirectory: false,
+  size: 4096
+});
+
+/**
+ * @type {string}
+ * @const
+ */
+var TESTING_ONLY_SIZE_FILE_NAME = 'only-size.txt';
+
+/**
  * Returns metadata for a requested entry.
  *
  * @param {GetMetadataRequestedOptions} options Options.
@@ -66,6 +96,16 @@
     return;
   }
 
+  if (options.entryPath === '/' + TESTING_ONLY_BASIC_FILE_NAME) {
+    onSuccess(TESTING_ONLY_BASIC_FILE);
+    return;
+  }
+
+  if (options.entryPath === '/' + TESTING_ONLY_SIZE_FILE_NAME) {
+    onSuccess(TESTING_ONLY_SIZE_FILE);
+    return;
+  }
+
   onError('NOT_FOUND');  // enum ProviderError.
 }
 
@@ -170,6 +210,59 @@
           chrome.test.callbackPass(function(error) {
             chrome.test.assertEq('TypeMismatchError', error.name);
           }));
+    },
+
+    // Resolving a file should only request is_directory and name fields.
+    function getMetadataForGetFile() {
+      test_util.fileSystem.root.getFile(
+          TESTING_ONLY_BASIC_FILE_NAME,
+          {create: false},
+          chrome.test.callbackPass(function(fileEntry) {
+            chrome.test.assertTrue(!!fileEntry);
+          }),
+          function(error) {
+            chrome.test.fail(error.name);
+          });
+    },
+
+    // Check that if a requested mandatory field is missing, then the error
+    // callback is invoked.
+    function getMetadataMissingFields() {
+      test_util.fileSystem.root.getFile(
+          TESTING_ONLY_SIZE_FILE_NAME,
+          {create: false},
+          chrome.test.callbackPass(function(fileEntry) {
+            fileEntry.getMetadata(
+                function(metadata) {
+                  chrome.test.fail('Unexpected success');
+                },
+                chrome.test.callbackPass(function(error) {
+                  chrome.test.assertEq('InvalidStateError', error.name);
+                }));
+          }),
+          function(error) {
+            chrome.test.fail(error.name);
+          });
+    },
+
+    // Fetch only requested fields.
+    function getEntryPropertiesFewFields() {
+      test_util.fileSystem.root.getFile(
+          TESTING_ONLY_SIZE_FILE_NAME,
+          {create: false},
+          chrome.test.callbackPass(function(fileEntry) {
+            chrome.fileManagerPrivate.getEntryProperties(
+                [fileEntry],
+                ['size'],
+                chrome.test.callbackPass(function(fileProperties) {
+                  chrome.test.assertEq(1, fileProperties.length);
+                  chrome.test.assertEq(
+                      TESTING_ONLY_SIZE_FILE.size, fileProperties[0].size);
+                }));
+            }),
+            function(error) {
+              chrome.test.fail(error.name);
+            });
     }
   ]);
 }
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/read_directory/test.js b/chrome/test/data/extensions/api_test/file_system_provider/read_directory/test.js
index 3879a7f..10c96c7 100644
--- a/chrome/test/data/extensions/api_test/file_system_provider/read_directory/test.js
+++ b/chrome/test/data/extensions/api_test/file_system_provider/read_directory/test.js
@@ -10,9 +10,7 @@
  */
 var TESTING_HELLO_DIR = Object.freeze({
   isDirectory: true,
-  name: 'hello',
-  size: 0,
-  modificationTime: new Date(2014, 3, 27, 9, 38, 14)
+  name: 'hello'
 });
 
 /**
@@ -21,9 +19,7 @@
  */
 var TESTING_CANDIES_DIR = Object.freeze({
   isDirectory: true,
-  name: 'candies',
-  size: 0,
-  modificationTime: new Date(2014, 2, 26, 8, 37, 13)
+  name: 'candies'
 });
 
 /**
@@ -32,9 +28,7 @@
  */
 var TESTING_TIRAMISU_FILE = Object.freeze({
   isDirectory: false,
-  name: 'tiramisu.txt',
-  size: 1986,
-  modificationTime: new Date(2014, 1, 25, 7, 36, 12)
+  name: 'tiramisu.txt'
 });
 
 /**
diff --git a/chrome/test/data/webui/history_browsertest.js b/chrome/test/data/webui/history_browsertest.js
index d49ee8b..d8792ea 100644
--- a/chrome/test/data/webui/history_browsertest.js
+++ b/chrome/test/data/webui/history_browsertest.js
@@ -775,17 +775,6 @@
     // Add a visit on the next day.
     GEN('  AddPageToHistory(36, "http://google.com", "Google");');
   },
-
-  /** @override */
-  setUp: function() {
-    BaseHistoryWebUITest.prototype.setUp.call(this);
-
-    // Enable when failure is resolved.
-    // AX_TEXT_04: http://crbug.com/560914
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'linkWithUnclearPurpose',
-        '#notification-bar > A');
-  },
 };
 
 /**
diff --git a/chrome/test/data/webui/net_internals/net_internals_test.js b/chrome/test/data/webui/net_internals/net_internals_test.js
index b381ec82..56bc93f6 100644
--- a/chrome/test/data/webui/net_internals/net_internals_test.js
+++ b/chrome/test/data/webui/net_internals/net_internals_test.js
@@ -56,8 +56,6 @@
     isAsync: true,
 
     setUp: function() {
-      testing.Test.prototype.setUp.call(this);
-
       // Enforce accessibility auditing, but suppress some false positives.
       this.accessibilityIssuesAreErrors = true;
       // False positive because a unicode character is used to draw a square.
@@ -81,25 +79,6 @@
       this.accessibilityAuditConfig.auditRulesToIgnore.push(
           'focusableElementNotVisibleAndNotAriaHidden');
 
-      var controlsWithoutLabelSelectors = [
-        '#export-view-user-comments',
-        '#hsts-view-add-input',
-        '#hsts-view-delete-input',
-        '#hsts-view-query-input',
-      ];
-
-      // Enable when failure is resolved.
-      // AX_TEXT_01: http://crbug.com/559203
-      this.accessibilityAuditConfig.ignoreSelectors(
-          'controlsWithoutLabel',
-          controlsWithoutLabelSelectors);
-
-      // Enable when warning is resolved.
-      // AX_HTML_01: http://crbug.com/559204
-      this.accessibilityAuditConfig.ignoreSelectors(
-          'humanLangMissing',
-          'html');
-
       // Wrap g_browser.receive around a test function so that assert and expect
       // functions can be called from observers.
       g_browser.receive =
diff --git a/chrome/test/data/webui/print_preview.js b/chrome/test/data/webui/print_preview.js
index 7d84ef9..2ef9260 100644
--- a/chrome/test/data/webui/print_preview.js
+++ b/chrome/test/data/webui/print_preview.js
@@ -166,7 +166,6 @@
    * @override
    */
   setUp: function() {
-    testing.Test.prototype.setUp.call(this);
     Mock4JS.clearMocksToVerify();
 
     this.initialSettings_ = new print_preview.NativeInitialSettings(
@@ -190,12 +189,6 @@
     this.nativeLayer_ = printPreview.nativeLayer_;
 
     testing.Test.disableAnimationsAndTransitions();
-
-    // Enable when failure is resolved.
-    // AX_TEXT_03: http://crbug.com/559209
-    this.accessibilityAuditConfig.ignoreSelectors(
-        'multipleLabelableElementsPerLabel',
-        '#page-settings > .right-column > *');
   }
 };
 
diff --git a/chrome/test/data/webui/test_api.js b/chrome/test/data/webui/test_api.js
index 248929b..4c2243ed 100644
--- a/chrome/test/data/webui/test_api.js
+++ b/chrome/test/data/webui/test_api.js
@@ -168,10 +168,15 @@
     /**
      * Returns the configuration for the accessibility audit, creating it
      * on-demand.
-     * @return {!axs.AuditConfiguration}
+     * @return {axs.AuditConfiguration}
      */
     get accessibilityAuditConfig() {
-      if (!this.accessibilityAuditConfig_) {
+      // The axs namespace is not available in chromevox tests.
+      // Further, 'window' is not available in unit tests, but since the
+      // accessibility audit library pulls in the closure library,
+      // 'goog.global' has to be present if axs is, so we use that here.
+      if (!this.accessibilityAuditConfig_ &&
+          goog && goog.global && goog.global.axs) {
         this.accessibilityAuditConfig_ = new axs.AuditConfiguration();
 
         this.accessibilityAuditConfig_.showUnsupportedRulesWarning = false;
@@ -191,10 +196,6 @@
             // TODO(aboxhall): re-enable when crbug.com/267035 is fixed.
             // Until then it's just noise.
             "lowContrastElements",
-
-            // TODO(apacible): re-enable when following issue is fixed.
-            // github.com/GoogleChrome/accessibility-developer-tools/issues/251
-            "tableHasAppropriateHeaders",
         ];
       }
       return this.accessibilityAuditConfig_;
@@ -306,14 +307,17 @@
      * @type {Function}
      */
     setUp: function() {
-      // These should be ignored in many of the web UI tests.
-      // user-image-stream and supervised-user-creation-image-stream are
-      // streaming video elements used for capturing a user image so they
-      // won't have captions and should be ignored everywhere.
-      this.accessibilityAuditConfig.ignoreSelectors('videoWithoutCaptions',
-                                                    '.user-image-stream');
-      this.accessibilityAuditConfig.ignoreSelectors(
-          'videoWithoutCaptions', '.supervised-user-creation-image-stream');
+      var auditConfig = this.accessibilityAuditConfig;
+      if (auditConfig) {
+        // These should be ignored in many of the web UI tests.
+        // user-image-stream and supervised-user-creation-image-stream are
+        // streaming video elements used for capturing a user image so they
+        // won't have captions and should be ignored everywhere.
+        auditConfig.ignoreSelectors('videoWithoutCaptions',
+                                    '.user-image-stream');
+        auditConfig.ignoreSelectors(
+            'videoWithoutCaptions', '.supervised-user-creation-image-stream');
+      }
     },
 
     /**
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index fe4d52d..afdc5c7 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-7673.0.0
\ No newline at end of file
+7678.0.0
\ No newline at end of file
diff --git a/components/arc.gypi b/components/arc.gypi
index ccff1f3..3773f09 100644
--- a/components/arc.gypi
+++ b/components/arc.gypi
@@ -19,6 +19,8 @@
       'sources': [
         'arc/arc_bridge_service.cc',
         'arc/arc_bridge_service.h',
+        'arc/arc_bridge_service_impl.cc',
+        'arc/arc_bridge_service_impl.h',
         'arc/common/arc_host_messages.h',
         'arc/common/arc_instance_messages.h',
         'arc/common/arc_message_generator.cc',
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn
index e6d6cae..e6f40684 100644
--- a/components/arc/BUILD.gn
+++ b/components/arc/BUILD.gn
@@ -6,6 +6,8 @@
   sources = [
     "arc_bridge_service.cc",
     "arc_bridge_service.h",
+    "arc_bridge_service_impl.cc",
+    "arc_bridge_service_impl.h",
     "common/arc_message_generator.cc",
   ]
 
diff --git a/components/arc/arc_bridge_service.cc b/components/arc/arc_bridge_service.cc
index e2146c22..af2835d 100644
--- a/components/arc/arc_bridge_service.cc
+++ b/components/arc/arc_bridge_service.cc
@@ -5,57 +5,40 @@
 #include "components/arc/arc_bridge_service.h"
 
 #include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/prefs/pref_registry_simple.h"
-#include "base/prefs/pref_service.h"
-#include "base/task_runner_util.h"
+#include "base/sequenced_task_runner.h"
 #include "base/thread_task_runner_handle.h"
 #include "chromeos/chromeos_switches.h"
-#include "chromeos/dbus/dbus_method_call_status.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/session_manager_client.h"
-#include "components/arc/common/arc_host_messages.h"
-#include "components/arc/common/arc_instance_messages.h"
-#include "ipc/ipc_channel.h"
+#include "components/arc/arc_bridge_service_impl.h"
 
 namespace arc {
 
 namespace {
 
-const base::FilePath::CharType kArcBridgeSocketPath[] =
-    FILE_PATH_LITERAL("/home/chronos/ArcBridge/bridge.sock");
-
 // Weak pointer.  This class is owned by ChromeBrowserMainPartsChromeos.
 ArcBridgeService* g_arc_bridge_service = nullptr;
 
 }  // namespace
 
-ArcBridgeService::ArcBridgeService(
-    const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
-    const scoped_refptr<base::SequencedTaskRunner>& file_task_runner)
+ArcBridgeService::ArcBridgeService()
     : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()),
-      ipc_task_runner_(ipc_task_runner),
-      file_task_runner_(file_task_runner),
-      session_started_(false),
       available_(false),
-      state_(State::STOPPED),
-      weak_factory_(this) {
+      state_(State::STOPPED) {
   DCHECK(!g_arc_bridge_service);
   g_arc_bridge_service = this;
 }
 
 ArcBridgeService::~ArcBridgeService() {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  DCHECK(state_ == State::STOPPING || state_ == State::STOPPED);
-  DCHECK(g_arc_bridge_service);
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  DCHECK(state() == State::STOPPING || state() == State::STOPPED);
+  DCHECK(g_arc_bridge_service == this);
   g_arc_bridge_service = nullptr;
 }
 
 // static
 ArcBridgeService* ArcBridgeService::Get() {
   DCHECK(g_arc_bridge_service);
-  DCHECK(g_arc_bridge_service->origin_task_runner_->RunsTasksOnCurrentThread());
+  DCHECK(g_arc_bridge_service->origin_task_runner()->
+      RunsTasksOnCurrentThread());
   return g_arc_bridge_service;
 }
 
@@ -64,233 +47,37 @@
   return command_line->HasSwitch(chromeos::switches::kEnableArc);
 }
 
-void ArcBridgeService::DetectAvailability() {
-  chromeos::SessionManagerClient* session_manager_client =
-      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
-  session_manager_client->CheckArcAvailability(base::Bind(
-      &ArcBridgeService::OnArcAvailable, weak_factory_.GetWeakPtr()));
-}
-
-void ArcBridgeService::HandleStartup() {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  session_started_ = true;
-  PrerequisitesChanged();
-}
-
-void ArcBridgeService::Shutdown() {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  session_started_ = false;
-  PrerequisitesChanged();
-}
-
 void ArcBridgeService::AddObserver(Observer* observer) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
   observer_list_.AddObserver(observer);
 }
 
 void ArcBridgeService::RemoveObserver(Observer* observer) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
   observer_list_.RemoveObserver(observer);
 }
 
-void ArcBridgeService::PrerequisitesChanged() {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  if (state_ == State::STOPPED) {
-    if (!available_ || !session_started_)
-      return;
-    SocketConnect(base::FilePath(kArcBridgeSocketPath));
-  } else {
-    if (available_ && session_started_)
-      return;
-    StopInstance();
-  }
-}
-
-void ArcBridgeService::StopInstance() {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  if (state_ == State::STOPPED || state_ == State::STOPPING) {
-    VLOG(1) << "StopInstance() called when ARC is not running";
-    return;
-  }
-  if (state_ == State::CONNECTED || state_ == State::CONNECTING) {
-    // This was stopped before the D-Bus command to start the instance. Just
-    // close the socket (if it was opened).
-    if (state_ == State::CONNECTED) {
-      ipc_channel_.reset();
-    }
-    SetState(State::STOPPED);
-    return;
-  }
-
-  SetState(State::STOPPING);
-  chromeos::SessionManagerClient* session_manager_client =
-      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
-  session_manager_client->StopArcInstance(base::Bind(
-      &ArcBridgeService::OnInstanceStopped, weak_factory_.GetWeakPtr()));
-}
-
-bool ArcBridgeService::RegisterInputDevice(const std::string& name,
-                                           const std::string& device_type,
-                                           base::ScopedFD fd) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  if (state_ != State::READY) {
-    LOG(ERROR) << "Called RegisterInputDevice when the service is not ready";
-    return false;
-  }
-  return ipc_channel_->Send(new ArcInstanceMsg_RegisterInputDevice(
-      name, device_type, base::FileDescriptor(fd.Pass())));
-}
-
-void ArcBridgeService::SocketConnect(const base::FilePath& socket_path) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  if (state_ != State::STOPPED) {
-    VLOG(1) << "SocketConnect() called when instance is not stopped";
-    return;
-  }
-  SetState(State::CONNECTING);
-  base::PostTaskAndReplyWithResult(
-      file_task_runner_.get(), FROM_HERE,
-      base::Bind(&base::CreateDirectory, socket_path.DirName()),
-      base::Bind(&ArcBridgeService::SocketConnectAfterEnsureParentDirectory,
-                 weak_factory_.GetWeakPtr(), socket_path));
-}
-
-void ArcBridgeService::SocketConnectAfterEnsureParentDirectory(
-    const base::FilePath& socket_path,
-    bool directory_present) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  if (state_ != State::CONNECTING) {
-    VLOG(1) << "StopInstance() called while connecting";
-    return;
-  }
-  if (!directory_present) {
-    LOG(ERROR) << "Error creating directory for " << socket_path.value();
-    StopInstance();
-    return;
-  }
-
-  if (!Connect(IPC::ChannelHandle(socket_path.value()),
-               IPC::Channel::MODE_OPEN_NAMED_SERVER)) {
-    LOG(ERROR) << "Error connecting to " << socket_path.value();
-    StopInstance();
-    return;
-  }
-
-  base::PostTaskAndReplyWithResult(
-      file_task_runner_.get(), FROM_HERE,
-      // TODO(lhchavez): Tighten the security around the socket by tying it to
-      // the user the instance will run as.
-      base::Bind(&base::SetPosixFilePermissions, socket_path, 0777),
-      base::Bind(&ArcBridgeService::SocketConnectAfterSetSocketPermissions,
-                 weak_factory_.GetWeakPtr(), socket_path));
-}
-
-bool ArcBridgeService::Connect(const IPC::ChannelHandle& handle,
-                               IPC::Channel::Mode mode) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  if (state_ != State::CONNECTING) {
-    VLOG(1) << "StopInstance() called while connecting";
-    return false;
-  }
-
-  ipc_channel_ =
-      IPC::ChannelProxy::Create(handle, mode, this, ipc_task_runner_.get());
-  if (!ipc_channel_)
-    return false;
-  SetState(State::CONNECTED);
-  return true;
-}
-
-void ArcBridgeService::SocketConnectAfterSetSocketPermissions(
-    const base::FilePath& socket_path,
-    bool socket_permissions_success) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  if (state_ != State::CONNECTED) {
-    VLOG(1) << "StopInstance() called while connecting";
-    return;
-  }
-
-  if (!socket_permissions_success) {
-    LOG(ERROR) << "Error setting socket permissions for "
-               << socket_path.value();
-    StopInstance();
-    return;
-  }
-
-  SetState(State::STARTING);
-  chromeos::SessionManagerClient* session_manager_client =
-      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
-  session_manager_client->StartArcInstance(
-      socket_path.value(), base::Bind(&ArcBridgeService::OnInstanceStarted,
-                                      weak_factory_.GetWeakPtr()));
-}
-
-void ArcBridgeService::OnInstanceStarted(bool success) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  if (state_ != State::STARTING) {
-    VLOG(1) << "StopInstance() called while connecting";
-    return;
-  }
-  if (!success) {
-    LOG(ERROR) << "ARC instance unable to start. Shutting down the bridge";
-    StopInstance();
-    return;
-  }
-}
-
-void ArcBridgeService::OnInstanceBootPhase(InstanceBootPhase phase) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  // The state can be STARTING the first time this is called, and will then
-  // transition to READY after BRIDGE_READY has been passed.
-  if (state_ != State::STARTING && state_ != State::READY) {
-    VLOG(1) << "StopInstance() called while connecting";
-    return;
-  }
-  if (phase == InstanceBootPhase::BRIDGE_READY) {
-    SetState(State::READY);
-  }
-  FOR_EACH_OBSERVER(Observer, observer_list_, OnInstanceBootPhase(phase));
-}
-
 void ArcBridgeService::SetState(State state) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
   // DCHECK on enum classes not supported.
   DCHECK(state_ != state);
   state_ = state;
-  FOR_EACH_OBSERVER(Observer, observer_list_, OnStateChanged(state_));
+  FOR_EACH_OBSERVER(Observer, observer_list(), OnStateChanged(state_));
 }
 
-bool ArcBridgeService::OnMessageReceived(const IPC::Message& message) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  bool handled = true;
-
-  IPC_BEGIN_MESSAGE_MAP(ArcBridgeService, message)
-    IPC_MESSAGE_HANDLER(ArcInstanceHostMsg_InstanceBootPhase,
-                        OnInstanceBootPhase)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-
-  if (!handled)
-    LOG(ERROR) << "Invalid message with type = " << message.type();
-  return handled;
-}
-
-void ArcBridgeService::OnArcAvailable(bool available) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  if (available_ == available)
-    return;
+void ArcBridgeService::SetAvailable(bool available) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  DCHECK(available_ != available);
   available_ = available;
-  FOR_EACH_OBSERVER(Observer, observer_list_, OnAvailableChanged(available_));
-  PrerequisitesChanged();
+  FOR_EACH_OBSERVER(Observer, observer_list(), OnAvailableChanged(available_));
 }
 
-void ArcBridgeService::OnInstanceStopped(bool success) {
-  DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
-  // STOPPING is the only valid state for this function.
-  // DCHECK on enum classes not supported.
-  DCHECK(state_ == State::STOPPING);
-  ipc_channel_.reset();
-  SetState(State::STOPPED);
+// static
+scoped_ptr<ArcBridgeService> ArcBridgeService::Create(
+    const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& file_task_runner) {
+  return make_scoped_ptr(new ArcBridgeServiceImpl(ipc_task_runner,
+                                                  file_task_runner));
 }
 
 }  // namespace arc
diff --git a/components/arc/arc_bridge_service.h b/components/arc/arc_bridge_service.h
index 14fdf84..78e8fa8 100644
--- a/components/arc/arc_bridge_service.h
+++ b/components/arc/arc_bridge_service.h
@@ -5,24 +5,24 @@
 #ifndef COMPONENTS_ARC_ARC_BRIDGE_SERVICE_H_
 #define COMPONENTS_ARC_ARC_BRIDGE_SERVICE_H_
 
+#include "base/files/scoped_file.h"
 #include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/observer_list.h"
-#include "base/sequenced_task_runner.h"
 #include "components/arc/common/arc_message_types.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_message.h"
 
 namespace base {
 class CommandLine;
-}
+class SequencedTaskRunner;
+class SingleThreadTaskRunner;
+}  // namespace base
 
 namespace arc {
 
 // The Chrome-side service that handles ARC instances and ARC bridge creation.
 // This service handles the lifetime of ARC instances and sets up the
 // communication channel (the ARC bridge) used to send and receive messages.
-class ArcBridgeService : public IPC::Listener {
+class ArcBridgeService {
  public:
   // The possible states of the bridge.  In the normal flow, the state changes
   // in the following sequence:
@@ -79,10 +79,12 @@
     virtual ~Observer() {}
   };
 
-  ArcBridgeService(
+  virtual ~ArcBridgeService();
+
+  // Creates instance of |ArcBridgeService| for normal use.
+  static scoped_ptr<ArcBridgeService> Create(
       const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
       const scoped_refptr<base::SequencedTaskRunner>& file_task_runner);
-  ~ArcBridgeService() override;
 
   // Gets the global instance of the ARC Bridge Service. This can only be
   // called on the thread that this class was created on.
@@ -95,16 +97,16 @@
   // DetectAvailability() should be called once D-Bus is available. It will
   // call CheckArcAvailability() on the session_manager. This can only be
   // called on the thread that this class was created on.
-  void DetectAvailability();
+  virtual void DetectAvailability() = 0;
 
   // HandleStartup() should be called upon profile startup.  This will only
   // launch an instance if the instance service is available and it is enabled.
   // This can only be called on the thread that this class was created on.
-  void HandleStartup();
+  virtual void HandleStartup() = 0;
 
   // Shutdown() should be called when the browser is shutting down. This can
   // only be called on the thread that this class was created on.
-  void Shutdown();
+  virtual void Shutdown() = 0;
 
   // Adds or removes observers. This can only be called on the thread that this
   // class was created on.
@@ -123,73 +125,36 @@
   // OS Keyboard"), |device_type| the name of the device type (e.g. "keyboard")
   // and |fd| a file descriptor that emulates the kernel events of the device.
   // This can only be called on the thread that this class was created on.
-  bool RegisterInputDevice(const std::string& name,
-                           const std::string& device_type,
-                           base::ScopedFD fd);
+  virtual bool RegisterInputDevice(const std::string& name,
+                                   const std::string& device_type,
+                                   base::ScopedFD fd) = 0;
 
- private:
-  friend class ArcBridgeTest;
-  FRIEND_TEST_ALL_PREFIXES(ArcBridgeTest, Basic);
-  FRIEND_TEST_ALL_PREFIXES(ArcBridgeTest, ShutdownMidStartup);
-
-  // If all pre-requisites are true (ARC is available, it has been enabled, and
-  // the session has started), and ARC is stopped, start ARC. If ARC is running
-  // and the pre-requisites stop being true, stop ARC.
-  void PrerequisitesChanged();
-
-  // Binds to the socket specified by |socket_path|.
-  void SocketConnect(const base::FilePath& socket_path);
-
-  // Binds to the socket specified by |socket_path| after creating its parent
-  // directory is present.
-  void SocketConnectAfterEnsureParentDirectory(
-      const base::FilePath& socket_path,
-      bool directory_present);
-
-  // Internal connection method. Separated to make testing easier.
-  bool Connect(const IPC::ChannelHandle& handle, IPC::Channel::Mode mode);
-
-  // Finishes connecting after setting socket permissions.
-  void SocketConnectAfterSetSocketPermissions(const base::FilePath& socket_path,
-                                              bool socket_permissions_success);
-
-  // Stops the running instance.
-  void StopInstance();
-
-  // Called when the instance has reached a boot phase
-  void OnInstanceBootPhase(InstanceBootPhase phase);
+ protected:
+  ArcBridgeService();
 
   // Changes the current state and notifies all observers.
   void SetState(State state);
 
-  // IPC::Listener:
-  bool OnMessageReceived(const IPC::Message& message) override;
+  // Changes the current availability and notifies all observers.
+  void SetAvailable(bool availability);
 
-  // DBus callbacks.
-  void OnArcAvailable(bool available);
-  void OnInstanceStarted(bool success);
-  void OnInstanceStopped(bool success);
+  const scoped_refptr<base::SequencedTaskRunner>& origin_task_runner() const {
+    return origin_task_runner_;
+  }
 
+  base::ObserverList<Observer>& observer_list() { return observer_list_; }
+
+ private:
   scoped_refptr<base::SequencedTaskRunner> origin_task_runner_;
-  scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
-  scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
-
-  scoped_ptr<IPC::ChannelProxy> ipc_channel_;
 
   base::ObserverList<Observer> observer_list_;
 
-  // If the user's session has started.
-  bool session_started_;
-
   // If the ARC instance service is available.
   bool available_;
 
   // The current state of the bridge.
   ArcBridgeService::State state_;
 
-  // WeakPtrFactory to use callbacks.
-  base::WeakPtrFactory<ArcBridgeService> weak_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(ArcBridgeService);
 };
 
diff --git a/components/arc/arc_bridge_service_impl.cc b/components/arc/arc_bridge_service_impl.cc
new file mode 100644
index 0000000..1a1c954
--- /dev/null
+++ b/components/arc/arc_bridge_service_impl.cc
@@ -0,0 +1,254 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/arc/arc_bridge_service_impl.h"
+
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/pref_service.h"
+#include "base/sequenced_task_runner.h"
+#include "base/task_runner_util.h"
+#include "base/thread_task_runner_handle.h"
+#include "chromeos/chromeos_switches.h"
+#include "chromeos/dbus/dbus_method_call_status.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/session_manager_client.h"
+#include "components/arc/common/arc_host_messages.h"
+#include "components/arc/common/arc_instance_messages.h"
+#include "ipc/ipc_channel.h"
+
+namespace arc {
+
+namespace {
+
+const base::FilePath::CharType kArcBridgeSocketPath[] =
+    FILE_PATH_LITERAL("/home/chronos/ArcBridge/bridge.sock");
+
+}  // namespace
+
+ArcBridgeServiceImpl::ArcBridgeServiceImpl(
+    const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
+    const scoped_refptr<base::SequencedTaskRunner>& file_task_runner)
+    : ipc_task_runner_(ipc_task_runner),
+      file_task_runner_(file_task_runner),
+      session_started_(false),
+      weak_factory_(this) {
+}
+
+ArcBridgeServiceImpl::~ArcBridgeServiceImpl() {
+}
+
+void ArcBridgeServiceImpl::DetectAvailability() {
+  chromeos::SessionManagerClient* session_manager_client =
+      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
+  session_manager_client->CheckArcAvailability(base::Bind(
+      &ArcBridgeServiceImpl::OnArcAvailable, weak_factory_.GetWeakPtr()));
+}
+
+void ArcBridgeServiceImpl::HandleStartup() {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  session_started_ = true;
+  PrerequisitesChanged();
+}
+
+void ArcBridgeServiceImpl::Shutdown() {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  session_started_ = false;
+  PrerequisitesChanged();
+}
+
+void ArcBridgeServiceImpl::PrerequisitesChanged() {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  if (state() == State::STOPPED) {
+    if (!available() || !session_started_)
+      return;
+    SocketConnect(base::FilePath(kArcBridgeSocketPath));
+  } else {
+    if (available() && session_started_)
+      return;
+    StopInstance();
+  }
+}
+
+void ArcBridgeServiceImpl::StopInstance() {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  if (state() == State::STOPPED || state() == State::STOPPING) {
+    VLOG(1) << "StopInstance() called when ARC is not running";
+    return;
+  }
+  if (state() == State::CONNECTED || state() == State::CONNECTING) {
+    // This was stopped before the D-Bus command to start the instance. Just
+    // close the socket (if it was opened).
+    if (state() == State::CONNECTED) {
+      ipc_channel_.reset();
+    }
+    SetState(State::STOPPED);
+    return;
+  }
+
+  SetState(State::STOPPING);
+  chromeos::SessionManagerClient* session_manager_client =
+      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
+  session_manager_client->StopArcInstance(base::Bind(
+      &ArcBridgeServiceImpl::OnInstanceStopped, weak_factory_.GetWeakPtr()));
+}
+
+bool ArcBridgeServiceImpl::RegisterInputDevice(const std::string& name,
+                                               const std::string& device_type,
+                                               base::ScopedFD fd) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  if (state() != State::READY) {
+    LOG(ERROR) << "Called RegisterInputDevice when the service is not ready";
+    return false;
+  }
+  return ipc_channel_->Send(new ArcInstanceMsg_RegisterInputDevice(
+      name, device_type, base::FileDescriptor(fd.Pass())));
+}
+
+void ArcBridgeServiceImpl::SocketConnect(const base::FilePath& socket_path) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  if (state() != State::STOPPED) {
+    VLOG(1) << "SocketConnect() called when instance is not stopped";
+    return;
+  }
+  SetState(State::CONNECTING);
+  base::PostTaskAndReplyWithResult(
+      file_task_runner_.get(), FROM_HERE,
+      base::Bind(&base::CreateDirectory, socket_path.DirName()),
+      base::Bind(&ArcBridgeServiceImpl::SocketConnectAfterEnsureParentDirectory,
+                 weak_factory_.GetWeakPtr(), socket_path));
+}
+
+void ArcBridgeServiceImpl::SocketConnectAfterEnsureParentDirectory(
+    const base::FilePath& socket_path,
+    bool directory_present) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  if (state() != State::CONNECTING) {
+    VLOG(1) << "StopInstance() called while connecting";
+    return;
+  }
+  if (!directory_present) {
+    LOG(ERROR) << "Error creating directory for " << socket_path.value();
+    StopInstance();
+    return;
+  }
+
+  if (!Connect(IPC::ChannelHandle(socket_path.value()),
+               IPC::Channel::MODE_OPEN_NAMED_SERVER)) {
+    LOG(ERROR) << "Error connecting to " << socket_path.value();
+    StopInstance();
+    return;
+  }
+
+  base::PostTaskAndReplyWithResult(
+      file_task_runner_.get(), FROM_HERE,
+      // TODO(lhchavez): Tighten the security around the socket by tying it to
+      // the user the instance will run as.
+      base::Bind(&base::SetPosixFilePermissions, socket_path, 0777),
+      base::Bind(&ArcBridgeServiceImpl::SocketConnectAfterSetSocketPermissions,
+                 weak_factory_.GetWeakPtr(), socket_path));
+}
+
+bool ArcBridgeServiceImpl::Connect(const IPC::ChannelHandle& handle,
+                                   IPC::Channel::Mode mode) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  if (state() != State::CONNECTING) {
+    VLOG(1) << "StopInstance() called while connecting";
+    return false;
+  }
+
+  ipc_channel_ =
+      IPC::ChannelProxy::Create(handle, mode, this, ipc_task_runner_.get());
+  if (!ipc_channel_)
+    return false;
+  SetState(State::CONNECTED);
+  return true;
+}
+
+void ArcBridgeServiceImpl::SocketConnectAfterSetSocketPermissions(
+    const base::FilePath& socket_path,
+    bool socket_permissions_success) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  if (state() != State::CONNECTED) {
+    VLOG(1) << "StopInstance() called while connecting";
+    return;
+  }
+
+  if (!socket_permissions_success) {
+    LOG(ERROR) << "Error setting socket permissions for "
+               << socket_path.value();
+    StopInstance();
+    return;
+  }
+
+  SetState(State::STARTING);
+  chromeos::SessionManagerClient* session_manager_client =
+      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
+  session_manager_client->StartArcInstance(
+      socket_path.value(), base::Bind(&ArcBridgeServiceImpl::OnInstanceStarted,
+                                      weak_factory_.GetWeakPtr()));
+}
+
+void ArcBridgeServiceImpl::OnInstanceStarted(bool success) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  if (state() != State::STARTING) {
+    VLOG(1) << "StopInstance() called while connecting";
+    return;
+  }
+  if (!success) {
+    LOG(ERROR) << "ARC instance unable to start. Shutting down the bridge";
+    StopInstance();
+    return;
+  }
+}
+
+void ArcBridgeServiceImpl::OnInstanceBootPhase(InstanceBootPhase phase) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  // The state can be STARTING the first time this is called, and will then
+  // transition to READY after BRIDGE_READY has been passed.
+  if (state() != State::STARTING && state() != State::READY) {
+    VLOG(1) << "StopInstance() called while connecting";
+    return;
+  }
+  if (phase == InstanceBootPhase::BRIDGE_READY) {
+    SetState(State::READY);
+  }
+  FOR_EACH_OBSERVER(Observer, observer_list(), OnInstanceBootPhase(phase));
+}
+
+bool ArcBridgeServiceImpl::OnMessageReceived(const IPC::Message& message) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  bool handled = true;
+
+  IPC_BEGIN_MESSAGE_MAP(ArcBridgeServiceImpl, message)
+    IPC_MESSAGE_HANDLER(ArcInstanceHostMsg_InstanceBootPhase,
+                        OnInstanceBootPhase)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+
+  if (!handled)
+    LOG(ERROR) << "Invalid message with type = " << message.type();
+  return handled;
+}
+
+void ArcBridgeServiceImpl::OnArcAvailable(bool arc_available) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  if (available() == arc_available)
+    return;
+  SetAvailable(arc_available);
+  PrerequisitesChanged();
+}
+
+void ArcBridgeServiceImpl::OnInstanceStopped(bool success) {
+  DCHECK(origin_task_runner()->RunsTasksOnCurrentThread());
+  // STOPPING is the only valid state for this function.
+  // DCHECK on enum classes not supported.
+  DCHECK(state() == State::STOPPING);
+  ipc_channel_.reset();
+  SetState(State::STOPPED);
+}
+
+}  // namespace arc
diff --git a/components/arc/arc_bridge_service_impl.h b/components/arc/arc_bridge_service_impl.h
new file mode 100644
index 0000000..d65e712
--- /dev/null
+++ b/components/arc/arc_bridge_service_impl.h
@@ -0,0 +1,97 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_ARC_ARC_BRIDGE_SERVICE_IMPL_H_
+#define COMPONENTS_ARC_ARC_BRIDGE_SERVICE_IMPL_H_
+
+#include "base/files/scoped_file.h"
+#include "base/macros.h"
+#include "components/arc/arc_bridge_service.h"
+#include "ipc/ipc_channel_proxy.h"
+#include "ipc/ipc_listener.h"
+#include "ipc/ipc_message.h"
+
+namespace base {
+class SequencedTaskRunner;
+class SingleThreadTaskRunner;
+}  // namespace base
+
+namespace arc {
+
+// Real IPC based ArcBridgeService that is used in production.
+class ArcBridgeServiceImpl : public ArcBridgeService,
+                             public IPC::Listener {
+ public:
+  ArcBridgeServiceImpl(
+      const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
+      const scoped_refptr<base::SequencedTaskRunner>& file_task_runner);
+  ~ArcBridgeServiceImpl() override;
+
+  void DetectAvailability() override;
+
+  void HandleStartup() override;
+
+  void Shutdown() override;
+
+  bool RegisterInputDevice(const std::string& name,
+                           const std::string& device_type,
+                           base::ScopedFD fd) override;
+
+ private:
+  friend class ArcBridgeTest;
+  FRIEND_TEST_ALL_PREFIXES(ArcBridgeTest, Basic);
+  FRIEND_TEST_ALL_PREFIXES(ArcBridgeTest, ShutdownMidStartup);
+
+  // If all pre-requisites are true (ARC is available, it has been enabled, and
+  // the session has started), and ARC is stopped, start ARC. If ARC is running
+  // and the pre-requisites stop being true, stop ARC.
+  void PrerequisitesChanged();
+
+  // Binds to the socket specified by |socket_path|.
+  void SocketConnect(const base::FilePath& socket_path);
+
+  // Binds to the socket specified by |socket_path| after creating its parent
+  // directory is present.
+  void SocketConnectAfterEnsureParentDirectory(
+      const base::FilePath& socket_path,
+      bool directory_present);
+
+  // Internal connection method. Separated to make testing easier.
+  bool Connect(const IPC::ChannelHandle& handle, IPC::Channel::Mode mode);
+
+  // Finishes connecting after setting socket permissions.
+  void SocketConnectAfterSetSocketPermissions(const base::FilePath& socket_path,
+                                              bool socket_permissions_success);
+
+  // Stops the running instance.
+  void StopInstance();
+
+  // Called when the instance has reached a boot phase
+  void OnInstanceBootPhase(InstanceBootPhase phase);
+
+  // IPC::Listener:
+  bool OnMessageReceived(const IPC::Message& message) override;
+
+  // DBus callbacks.
+  void OnArcAvailable(bool available);
+  void OnInstanceStarted(bool success);
+  void OnInstanceStopped(bool success);
+
+  scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
+
+  scoped_ptr<IPC::ChannelProxy> ipc_channel_;
+
+  // If the user's session has started.
+  bool session_started_;
+
+  // WeakPtrFactory to use callbacks.
+  base::WeakPtrFactory<ArcBridgeServiceImpl> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ArcBridgeServiceImpl);
+};
+
+}  // namespace arc
+
+#endif  // COMPONENTS_ARC_ARC_BRIDGE_SERVICE_IMPL_H_
diff --git a/components/arc/arc_bridge_service_unittest.cc b/components/arc/arc_bridge_service_unittest.cc
index 5b765caf..a7860be 100644
--- a/components/arc/arc_bridge_service_unittest.cc
+++ b/components/arc/arc_bridge_service_unittest.cc
@@ -2,11 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/arc/arc_bridge_service.h"
-
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
+#include "components/arc/arc_bridge_service_impl.h"
 #include "components/arc/common/arc_host_messages.h"
 #include "ipc/ipc_channel.h"
 #include "ipc/ipc_channel_proxy.h"
@@ -79,7 +78,7 @@
  protected:
   scoped_ptr<IPCSenderFake> fake_sender_;
 
-  scoped_ptr<ArcBridgeService> service_;
+  scoped_ptr<ArcBridgeServiceImpl> service_;
 
  private:
   void SetUp() override {
@@ -91,8 +90,8 @@
     ipc_thread_.reset(new base::Thread("IPC thread"));
     ipc_thread_->StartWithOptions(
         base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
-    service_.reset(new ArcBridgeService(ipc_thread_->task_runner(),
-                                        message_loop_.task_runner()));
+    service_.reset(new ArcBridgeServiceImpl(ipc_thread_->task_runner(),
+                                            message_loop_.task_runner()));
 
     service_->AddObserver(this);
 
diff --git a/components/autofill.gypi b/components/autofill.gypi
index e494a094..af4f855 100644
--- a/components/autofill.gypi
+++ b/components/autofill.gypi
@@ -50,8 +50,6 @@
         'autofill/core/common/password_generation_util.h',
         'autofill/core/common/save_password_progress_logger.cc',
         'autofill/core/common/save_password_progress_logger.h',
-        'autofill/core/common/web_element_descriptor.cc',
-        'autofill/core/common/web_element_descriptor.h',
       ],
 
       # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
@@ -77,9 +75,9 @@
         '../third_party/fips181/fips181.gyp:fips181',
         '../third_party/icu/icu.gyp:icui18n',
         '../third_party/icu/icu.gyp:icuuc',
-        '../third_party/libjingle/libjingle.gyp:libjingle',
         '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_util',
         '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber',
+        '../third_party/libxml/libxml.gyp:libxml',
         '../third_party/re2/re2.gyp:re2',
         '../ui/base/ui_base.gyp:ui_base',
         '../ui/gfx/gfx.gyp:gfx',
diff --git a/components/autofill/content/common/autofill_messages.h b/components/autofill/content/common/autofill_messages.h
index ed6e6d4..b3878cb 100644
--- a/components/autofill/content/common/autofill_messages.h
+++ b/components/autofill/content/common/autofill_messages.h
@@ -17,7 +17,6 @@
 #include "components/autofill/core/common/password_form.h"
 #include "components/autofill/core/common/password_form_field_prediction_map.h"
 #include "components/autofill/core/common/password_form_fill_data.h"
-#include "components/autofill/core/common/web_element_descriptor.h"
 #include "content/public/common/common_param_traits.h"
 #include "content/public/common/common_param_traits_macros.h"
 #include "ipc/ipc_message_macros.h"
@@ -39,14 +38,6 @@
 IPC_ENUM_TRAITS_MAX_VALUE(base::i18n::TextDirection,
                           base::i18n::TEXT_DIRECTION_NUM_DIRECTIONS - 1)
 
-IPC_STRUCT_TRAITS_BEGIN(autofill::WebElementDescriptor)
-  IPC_STRUCT_TRAITS_MEMBER(descriptor)
-  IPC_STRUCT_TRAITS_MEMBER(retrieval_method)
-IPC_STRUCT_TRAITS_END()
-
-IPC_ENUM_TRAITS_MAX_VALUE(autofill::WebElementDescriptor::RetrievalMethod,
-                          autofill::WebElementDescriptor::NONE)
-
 IPC_STRUCT_TRAITS_BEGIN(autofill::FormFieldData)
   IPC_STRUCT_TRAITS_MEMBER(label)
   IPC_STRUCT_TRAITS_MEMBER(name)
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index dae948b..d2bea33 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -30,7 +30,6 @@
 #include "components/autofill/core/common/form_data_predictions.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "components/autofill/core/common/password_form.h"
-#include "components/autofill/core/common/web_element_descriptor.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/ssl_status.h"
 #include "content/public/common/url_constants.h"
diff --git a/components/autofill/content/renderer/autofill_agent.h b/components/autofill/content/renderer/autofill_agent.h
index 6072eda..2471403 100644
--- a/components/autofill/content/renderer/autofill_agent.h
+++ b/components/autofill/content/renderer/autofill_agent.h
@@ -30,7 +30,6 @@
 
 struct FormData;
 struct FormFieldData;
-struct WebElementDescriptor;
 class PasswordAutofillAgent;
 class PasswordGenerationAgent;
 
diff --git a/components/autofill/content/renderer/form_autofill_util.h b/components/autofill/content/renderer/form_autofill_util.h
index 5632c66..dd1b1271b 100644
--- a/components/autofill/content/renderer/form_autofill_util.h
+++ b/components/autofill/content/renderer/form_autofill_util.h
@@ -30,7 +30,6 @@
 
 struct FormData;
 struct FormFieldData;
-struct WebElementDescriptor;
 
 namespace form_util {
 
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index ee20687..1dcf74f 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -180,8 +180,8 @@
     "//third_party/fips181",
     "//third_party/icu",
     "//third_party/libaddressinput:util",
-    "//third_party/libjingle",
     "//third_party/libphonenumber",
+    "//third_party/libxml",
     "//third_party/re2",
     "//ui/base",
     "//ui/gfx",
@@ -309,7 +309,6 @@
     "//testing/gmock",
     "//testing/gtest",
     "//third_party/libaddressinput:util",
-    "//third_party/libjingle",
     "//third_party/libphonenumber",
     "//ui/base",
     "//url",
diff --git a/components/autofill/core/browser/DEPS b/components/autofill/core/browser/DEPS
index 164b1d9a..b19a8c84 100644
--- a/components/autofill/core/browser/DEPS
+++ b/components/autofill/core/browser/DEPS
@@ -15,10 +15,9 @@
   "+sql",
   "+sync",
   "+third_party/fips181",
-  "+third_party/libjingle",
-  "+third_party/webrtc/libjingle",
   "+third_party/libaddressinput", # For address i18n.
   "+third_party/libphonenumber",  # For phone number i18n.
+  "+third_party/libxml",
   "+third_party/re2",
   "+ui/base",
   "+ui/gfx",
diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc
index 17ffec1..38c8484 100644
--- a/components/autofill/core/browser/autofill_download_manager.cc
+++ b/components/autofill/core/browser/autofill_download_manager.cc
@@ -4,6 +4,8 @@
 
 #include "components/autofill/core/browser/autofill_download_manager.h"
 
+#include <utility>
+
 #include "base/logging.h"
 #include "base/prefs/pref_service.h"
 #include "base/rand_util.h"
@@ -21,7 +23,6 @@
 #include "net/http/http_request_headers.h"
 #include "net/http/http_response_headers.h"
 #include "net/url_request/url_fetcher.h"
-#include "third_party/webrtc/libjingle/xmllite/xmlparser.h"
 #include "url/gurl.h"
 
 namespace autofill {
@@ -119,7 +120,7 @@
     VLOG(1) << "AutofillDownloadManager: query request has been retrieved "
              << "from the cache, form signatures: "
              << GetCombinedSignature(request_data.form_signatures);
-    observer_->OnLoadedServerPredictions(query_data,
+    observer_->OnLoadedServerPredictions(std::move(query_data),
                                          request_data.form_signatures);
     return true;
   }
@@ -342,16 +343,14 @@
              << " request has succeeded with response body: " << response_body;
     if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) {
       CacheQueryRequest(it->second.form_signatures, response_body);
-      observer_->OnLoadedServerPredictions(response_body,
+      observer_->OnLoadedServerPredictions(std::move(response_body),
                                            it->second.form_signatures);
     } else {
       double new_positive_upload_rate = 0;
       double new_negative_upload_rate = 0;
-      AutofillUploadXmlParser parse_handler(&new_positive_upload_rate,
-                                            &new_negative_upload_rate);
-      buzz::XmlParser parser(&parse_handler);
-      parser.Parse(response_body.data(), response_body.length(), true);
-      if (parse_handler.succeeded()) {
+      if (ParseAutofillUploadXml(std::move(response_body),
+                                 &new_positive_upload_rate,
+                                 &new_negative_upload_rate)) {
         SetPositiveUploadRate(new_positive_upload_rate);
         SetNegativeUploadRate(new_negative_upload_rate);
       }
diff --git a/components/autofill/core/browser/autofill_download_manager.h b/components/autofill/core/browser/autofill_download_manager.h
index b48764c..8dedb72 100644
--- a/components/autofill/core/browser/autofill_download_manager.h
+++ b/components/autofill/core/browser/autofill_download_manager.h
@@ -41,7 +41,7 @@
     // server. |response_xml| contains the server response for the forms
     // represented by |form_signatures|.
     virtual void OnLoadedServerPredictions(
-        const std::string& response_xml,
+        std::string response_xml,
         const std::vector<std::string>& form_signatures) = 0;
 
     // These notifications are used to help with testing.
diff --git a/components/autofill/core/browser/autofill_download_manager_unittest.cc b/components/autofill/core/browser/autofill_download_manager_unittest.cc
index 2373091..2982ae12 100644
--- a/components/autofill/core/browser/autofill_download_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/autofill/core/browser/autofill_download_manager.h"
 
 #include <list>
+#include <utility>
 
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_number_conversions.h"
@@ -81,10 +82,10 @@
 
   // AutofillDownloadManager::Observer implementation.
   void OnLoadedServerPredictions(
-      const std::string& response_xml,
+      std::string response_xml,
       const std::vector<std::string>& form_signatures) override {
     ResponseData response;
-    response.response = response_xml;
+    response.response = std::move(response_xml);
     response.type_of_response = QUERY_SUCCESSFULL;
     responses_.push_back(response);
   }
@@ -173,7 +174,7 @@
   field.form_control_type = "submit";
   form.fields.push_back(field);
 
-  FormStructure *form_structure = new FormStructure(form);
+  FormStructure* form_structure = new FormStructure(form);
   ScopedVector<FormStructure> form_structures;
   form_structures.push_back(form_structure);
 
@@ -431,7 +432,7 @@
   field.name = ASCIIToUTF16("lastname");
   form.fields.push_back(field);
 
-  FormStructure *form_structure = new FormStructure(form);
+  FormStructure* form_structure = new FormStructure(form);
   ScopedVector<FormStructure> form_structures0;
   form_structures0.push_back(form_structure);
 
@@ -562,13 +563,13 @@
 TEST_F(AutofillDownloadTest, QueryRequestIsGzipped) {
   // Expected query (uncompressed for visual verification).
   const char* kExpectedQueryXml =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+      "<?xml version=\"1.0\"?>\n"
       "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
       "<form signature=\"14546501144368603154\">"
       "<field signature=\"239111655\"/>"
       "<field signature=\"3763331450\"/>"
       "<field signature=\"3494530716\"/>"
-      "</form></autofillquery>";
+      "</form></autofillquery>\n";
 
   // Create and register factory.
   net::TestURLFetcherFactory factory;
@@ -613,16 +614,16 @@
   EXPECT_EQ("gzip", header);
 
   // Expect that the compression is logged.
-  histogram.ExpectUniqueSample("Autofill.PayloadCompressionRatio.Query", 73, 1);
+  histogram.ExpectUniqueSample("Autofill.PayloadCompressionRatio.Query", 72, 1);
 }
 
 TEST_F(AutofillDownloadTest, UploadRequestIsGzipped) {
   // Expected upload (uncompressed for visual verification).
   const char* kExpectedUploadXml =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+      "<?xml version=\"1.0\"?>\n"
       "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
       " formsignature=\"14546501144368603154\" autofillused=\"true\""
-      " datapresent=\"\"/>";
+      " datapresent=\"\"/>\n";
 
   // Create and register factory.
   net::TestURLFetcherFactory factory;
@@ -670,7 +671,7 @@
   EXPECT_EQ("gzip", header);
 
   // Expect that the compression is logged.
-  histogram.ExpectUniqueSample("Autofill.PayloadCompressionRatio.Upload", 92,
+  histogram.ExpectUniqueSample("Autofill.PayloadCompressionRatio.Upload", 95,
                                1);
 }
 
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 0d3c169..e3c5e3c6 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -743,7 +743,7 @@
 }
 
 void AutofillManager::OnLoadedServerPredictions(
-    const std::string& response_xml,
+    std::string response_xml,
     const std::vector<std::string>& form_signatures) {
   // We obtain the current valid FormStructures represented by
   // |form_signatures|. We invert both lists because most recent forms are at
@@ -765,7 +765,7 @@
     return;
 
   // Parse and store the server predictions.
-  FormStructure::ParseQueryResponse(response_xml, queried_forms,
+  FormStructure::ParseQueryResponse(std::move(response_xml), queried_forms,
                                     client_->GetRapporService());
 
   // Forward form structures to the password generation manager to detect
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 03438286..aac1d95 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -247,7 +247,7 @@
  private:
   // AutofillDownloadManager::Observer:
   void OnLoadedServerPredictions(
-      const std::string& response_xml,
+      std::string response_xml,
       const std::vector<std::string>& form_signatures) override;
 
   // CardUnmaskDelegate:
diff --git a/components/autofill/core/browser/autofill_xml_parser.cc b/components/autofill/core/browser/autofill_xml_parser.cc
index 6059b57..7dec347 100644
--- a/components/autofill/core/browser/autofill_xml_parser.cc
+++ b/components/autofill/core/browser/autofill_xml_parser.cc
@@ -4,176 +4,112 @@
 
 #include "components/autofill/core/browser/autofill_xml_parser.h"
 
-#include <string.h>
+#include <utility>
 
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "components/autofill/core/browser/autofill_server_field_info.h"
-#include "third_party/webrtc/libjingle/xmllite/qname.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "third_party/libxml/chromium/libxml_utils.h"
 
 namespace autofill {
 
-AutofillXmlParser::AutofillXmlParser()
-    : succeeded_(true) {
-}
+bool ParseAutofillQueryXml(std::string xml,
+                           std::vector<AutofillServerFieldInfo>* field_infos,
+                           UploadRequired* upload_required) {
+  DCHECK(field_infos);
+  DCHECK(upload_required);
 
-AutofillXmlParser::~AutofillXmlParser() {}
+  XmlReader reader;
+  if (!reader.Load(xml))
+    return false;
 
-void AutofillXmlParser::CharacterData(
-    buzz::XmlParseContext* context, const char* text, int len) {
-}
+  // Seek to the first opening tag.
+  if (!reader.Read())
+    return false;  // Malformed input.
 
-void AutofillXmlParser::EndElement(buzz::XmlParseContext* context,
-                                   const char* name) {
-}
+  if (reader.NodeName() != "autofillqueryresponse")
+    return false;  // Malformed input.
 
-void AutofillXmlParser::Error(buzz::XmlParseContext* context,
-                              XML_Error error_code) {
-  succeeded_ = false;
-}
+  *upload_required = USE_UPLOAD_RATES;
+  std::string upload_required_value;
+  if (reader.NodeAttribute("uploadrequired", &upload_required_value)) {
+    if (upload_required_value == "true")
+      *upload_required = UPLOAD_REQUIRED;
+    else if (upload_required_value == "false")
+      *upload_required = UPLOAD_NOT_REQUIRED;
+  }
 
-AutofillQueryXmlParser::AutofillQueryXmlParser(
-    std::vector<AutofillServerFieldInfo>* field_infos,
-    UploadRequired* upload_required)
-    : field_infos_(field_infos),
-      upload_required_(upload_required) {
-  DCHECK(upload_required_);
-}
+  field_infos->clear();
+  if (reader.IsClosingElement())
+    return true;
 
-AutofillQueryXmlParser::~AutofillQueryXmlParser() {}
-
-void AutofillQueryXmlParser::StartElement(buzz::XmlParseContext* context,
-                                          const char* name,
-                                          const char** attrs) {
-  buzz::QName qname = context->ResolveQName(name, false);
-  const std::string& element = qname.LocalPart();
-  if (element.compare("autofillqueryresponse") == 0) {
-    // We check for the upload required attribute below, but if it's not
-    // present, we use the default upload rates.
-    *upload_required_ = USE_UPLOAD_RATES;
-
-    // |attrs| is a NULL-terminated list of (attribute, value) pairs.
-    while (*attrs) {
-      buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
-      ++attrs;
-      const std::string& attribute_name = attribute_qname.LocalPart();
-      if (attribute_name.compare("uploadrequired") == 0) {
-        if (strcmp(*attrs, "true") == 0)
-          *upload_required_ = UPLOAD_REQUIRED;
-        else if (strcmp(*attrs, "false") == 0)
-          *upload_required_ = UPLOAD_NOT_REQUIRED;
-      }
-      ++attrs;
-    }
-  } else if (element.compare("field") == 0) {
-    if (!*attrs) {
-      // Missing the "autofilltype" attribute, abort.
-      context->RaiseError(XML_ERROR_ABORTED);
-      return;
-    }
-
-    // Determine the field type from the attribute value.  There should be one
-    // attribute (autofilltype) with an integer value.
+  if (!reader.Read())
+    return false;  // Malformed input.
+  while (reader.NodeName() == "field") {
     AutofillServerFieldInfo field_info;
     field_info.field_type = UNKNOWN_TYPE;
 
-    // |attrs| is a NULL-terminated list of (attribute, value) pairs.
-    while (*attrs) {
-      buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
-      ++attrs;
-      const std::string& attribute_name = attribute_qname.LocalPart();
-      if (attribute_name.compare("autofilltype") == 0) {
-        int value = GetIntValue(context, *attrs);
-        if (value >= 0 && value < MAX_VALID_FIELD_TYPE)
-          field_info.field_type = static_cast<ServerFieldType>(value);
-        else
-          field_info.field_type = NO_SERVER_DATA;
-      } else if (field_info.field_type == FIELD_WITH_DEFAULT_VALUE &&
-                 attribute_name.compare("defaultvalue") == 0) {
-        field_info.default_value = *attrs;
-      }
-      ++attrs;
+    std::string autofill_type_value;
+    if (!reader.NodeAttribute("autofilltype", &autofill_type_value))
+      return false;  // Missing required attribute.
+    int parsed_type = 0;
+    if (!base::StringToInt(autofill_type_value, &parsed_type) ||
+        parsed_type < 0 || parsed_type >= MAX_VALID_FIELD_TYPE) {
+      // Invalid attribute value should not make the whole parse fail.
+      field_info.field_type = NO_SERVER_DATA;
+    } else {
+      field_info.field_type = static_cast<ServerFieldType>(parsed_type);
     }
 
-    // Record this field type, default value pair.
-    field_infos_->push_back(field_info);
-  }
-}
-
-void AutofillQueryXmlParser::ParseElementDescriptor(
-    buzz::XmlParseContext* context,
-    const char* const* attrs,
-    WebElementDescriptor* element_descriptor) {
-  // If both id and css_selector are set, the first one to appear will take
-  // precedence.
-  // |attrs| is a NULL-terminated list of (attribute, value) pairs.
-  while (*attrs) {
-    buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
-    ++attrs;
-    const std::string& attribute_name = attribute_qname.LocalPart();
-    buzz::QName value_qname = context->ResolveQName(*attrs, true);
-    ++attrs;
-    const std::string& attribute_value = value_qname.LocalPart();
-    if (attribute_name.compare("id") == 0 && !attribute_value.empty()) {
-      element_descriptor->retrieval_method = WebElementDescriptor::ID;
-      element_descriptor->descriptor = attribute_value;
-      break;
-    } else if (attribute_name.compare("css_selector") == 0 &&
-               !attribute_value.empty()) {
-      element_descriptor->retrieval_method = WebElementDescriptor::CSS_SELECTOR;
-      element_descriptor->descriptor = attribute_value;
-      break;
+    std::string default_value;
+    if (field_info.field_type == FIELD_WITH_DEFAULT_VALUE &&
+        reader.NodeAttribute("defaultvalue", &default_value)) {
+      field_info.default_value = std::move(default_value);
     }
+
+    field_infos->push_back(field_info);
+
+    if (!reader.Read())
+      return false;  // Malformed input.
   }
+
+  if (reader.NodeName() != "autofillqueryresponse" ||
+      !reader.IsClosingElement()) {
+    return false;  // Malformed input.
+  }
+  return true;
 }
 
-int AutofillQueryXmlParser::GetIntValue(buzz::XmlParseContext* context,
-                                        const char* attribute) {
-  int value = 0;
-  if (!base::StringToInt(attribute, &value)) {
-    context->RaiseError(XML_ERROR_SYNTAX);
-    return 0;
-  }
-  return value;
-}
+bool ParseAutofillUploadXml(std::string xml,
+                            double* positive_upload_rate,
+                            double* negative_upload_rate) {
+  DCHECK(positive_upload_rate);
+  DCHECK(negative_upload_rate);
 
-AutofillUploadXmlParser::AutofillUploadXmlParser(double* positive_upload_rate,
-                                                 double* negative_upload_rate)
-    : succeeded_(false),
-      positive_upload_rate_(positive_upload_rate),
-      negative_upload_rate_(negative_upload_rate) {
-  DCHECK(positive_upload_rate_);
-  DCHECK(negative_upload_rate_);
-}
+  XmlReader reader;
+  if (!reader.Load(xml))
+    return false;
 
-void AutofillUploadXmlParser::StartElement(buzz::XmlParseContext* context,
-                                           const char* name,
-                                           const char** attrs) {
-  buzz::QName qname = context->ResolveQName(name, false);
-  const std::string &element = qname.LocalPart();
-  if (element.compare("autofilluploadresponse") == 0) {
-    // Loop over all attributes to get the upload rates.
-    while (*attrs) {
-      buzz::QName attribute_qname = context->ResolveQName(attrs[0], true);
-      const std::string &attribute_name = attribute_qname.LocalPart();
-      if (attribute_name.compare("positiveuploadrate") == 0) {
-        *positive_upload_rate_ = GetDoubleValue(context, attrs[1]);
-      } else if (attribute_name.compare("negativeuploadrate") == 0) {
-        *negative_upload_rate_ = GetDoubleValue(context, attrs[1]);
-      }
-      attrs += 2;  // We peeked at attrs[0] and attrs[1], skip past both.
-    }
-  }
-}
+  // Seek to the first opening tag.
+  if (!reader.Read())
+    return false;  // Malformed input.
 
-double AutofillUploadXmlParser::GetDoubleValue(buzz::XmlParseContext* context,
-                                               const char* attribute) {
-  double value = 0;
-  if (!base::StringToDouble(attribute, &value)) {
-    context->RaiseError(XML_ERROR_SYNTAX);
-    return 0.0;
-  }
-  return value;
+  if (reader.NodeName() != "autofilluploadresponse")
+    return false;  // Malformed input.
+
+  std::string attribute_value;
+  // TODO(crbug.com/561619) Make the two attributes non-required and use 1 as
+  // the default value.
+  if (!reader.NodeAttribute("positiveuploadrate", &attribute_value))
+    return false;  // Missing required attribute.
+  if (!base::StringToDouble(attribute_value, positive_upload_rate))
+    return false;  // Invalid attribute value.
+  if (!reader.NodeAttribute("negativeuploadrate", &attribute_value))
+    return false;  // Missing required attribute.
+  if (!base::StringToDouble(attribute_value, negative_upload_rate))
+    return false;  // Invalid attribute value.
+  return true;
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_xml_parser.h b/components/autofill/core/browser/autofill_xml_parser.h
index 1f4e102..460dd3f 100644
--- a/components/autofill/core/browser/autofill_xml_parser.h
+++ b/components/autofill/core/browser/autofill_xml_parser.h
@@ -8,107 +8,37 @@
 #include <string>
 #include <vector>
 
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "components/autofill/core/browser/autofill_server_field_info.h"
-#include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/form_structure.h"
-#include "third_party/webrtc/libjingle/xmllite/xmlparser.h"
 
 namespace autofill {
 
-// The base class that contains common functionality between
-// AutofillQueryXmlParser and AutofillUploadXmlParser.
-class AutofillXmlParser : public buzz::XmlParseHandler {
- public:
-  AutofillXmlParser();
-  ~AutofillXmlParser() override;
+struct AutofillServerFieldInfo;
 
-  // Returns true if no parsing errors were encountered.
-  bool succeeded() const { return succeeded_; }
-
- private:
-  // A callback for the end of an </element>, called by Expat.
-  // |context| is a parsing context used to resolve element/attribute names.
-  // |name| is the name of the element.
-  void EndElement(buzz::XmlParseContext* context, const char* name) override;
-
-  // The callback for character data between tags (<element>text...</element>).
-  // |context| is a parsing context used to resolve element/attribute names.
-  // |text| is a pointer to the beginning of character data (not null
-  // terminated).
-  // |len| is the length of the string pointed to by text.
-  void CharacterData(buzz::XmlParseContext* context,
-                     const char* text,
-                     int len) override;
-
-  // The callback for parsing errors.
-  // |context| is a parsing context used to resolve names.
-  // |error_code| is a code representing the parsing error.
-  void Error(buzz::XmlParseContext* context, XML_Error error_code) override;
-
-  // True if parsing succeeded.
-  bool succeeded_;
-
-  DISALLOW_COPY_AND_ASSIGN(AutofillXmlParser);
-};
-
-// The XML parse handler for parsing Autofill query responses.  A typical
-// response looks like:
+// The XML parser for parsing Autofill query responses.  A typical response
+// looks like:
 //
-// <autofillqueryresponse>
+// <autofillqueryresponse uploadrequired="true">
 //   <field autofilltype="0" />
 //   <field autofilltype="1" />
 //   <field autofilltype="3" />
 //   <field autofilltype="2" />
+//   <field autofilltype="61" defaultvalue="default" />
 // </autofillqueryresponse>
 //
 // Fields are returned in the same order they were sent to the server.
 // autofilltype: The server's guess at what type of field this is.  0
 // is unknown, other types are documented in
 // components/autofill/core/browser/field_types.h.
-class AutofillQueryXmlParser : public AutofillXmlParser {
- public:
-  AutofillQueryXmlParser(std::vector<AutofillServerFieldInfo>* field_infos,
-                         UploadRequired* upload_required);
-  ~AutofillQueryXmlParser() override;
+//
+// Parses |xml| and on success returns true and fills |field_infos| based on the
+// <field> tags and |upload_required| based on the uploadrequired attribute of
+// the autofillqueryresponse tag. On failure returns false.
+bool ParseAutofillQueryXml(std::string xml,
+                           std::vector<AutofillServerFieldInfo>* field_infos,
+                           UploadRequired* upload_required);
 
- private:
-  // A callback for the beginning of a new <element>, called by Expat.
-  // |context| is a parsing context used to resolve element/attribute names.
-  // |name| is the name of the element.
-  // |attrs| is the list of attributes (names and values) for the element.
-  void StartElement(buzz::XmlParseContext* context,
-                    const char* name,
-                    const char** attrs) override;
-
-  // A helper function to parse a |WebElementDescriptor|.
-  // |context| is the current parsing context.
-  // |attrs| is the list of attributes (names and values) for the element.
-  // |element_descriptor| will be populated by this function.
-  void ParseElementDescriptor(buzz::XmlParseContext* context,
-                              const char* const* attrs,
-                              WebElementDescriptor* element_descriptor);
-
-  // A helper function to retrieve integer values from strings.  Raises an
-  // XML parse error if it fails.
-  // |context| is the current parsing context.
-  // |value| is the string to convert.
-  int GetIntValue(buzz::XmlParseContext* context, const char* attribute);
-
-  // The parsed <field type, default value> pairs.
-  std::vector<AutofillServerFieldInfo>* field_infos_;
-
-  // A flag indicating whether the client should upload Autofill data when this
-  // form is submitted.
-  UploadRequired* upload_required_;
-
-  DISALLOW_COPY_AND_ASSIGN(AutofillQueryXmlParser);
-};
-
-// The XML parser for handling Autofill upload responses.  Typical upload
-// responses look like:
+// The XML parser for Autofill upload responses.  Typical upload responses look
+// like:
 //
 // <autofilluploadresponse negativeuploadrate="0.00125" positiveuploadrate="1"/>
 //
@@ -118,34 +48,12 @@
 // the form matches what's in the users profile.
 // The negative upload rate is typically much lower than the positive upload
 // rate.
-class AutofillUploadXmlParser : public AutofillXmlParser {
- public:
-  AutofillUploadXmlParser(double* positive_upload_rate,
-                          double* negative_upload_rate);
-
- private:
-  // A callback for the beginning of a new <element>, called by Expat.
-  // |context| is a parsing context used to resolve element/attribute names.
-  // |name| is the name of the element.
-  // |attrs| is the list of attributes (names and values) for the element.
-  void StartElement(buzz::XmlParseContext* context,
-                    const char* name,
-                    const char** attrs) override;
-
-  // A helper function to retrieve double values from strings.  Raises an XML
-  // parse error if it fails.
-  // |context| is the current parsing context.
-  // |value| is the string to convert.
-  double GetDoubleValue(buzz::XmlParseContext* context, const char* attribute);
-
-  // True if parsing succeeded.
-  bool succeeded_;
-
-  double* positive_upload_rate_;
-  double* negative_upload_rate_;
-
-  DISALLOW_COPY_AND_ASSIGN(AutofillUploadXmlParser);
-};
+//
+// Parses |xml| and on success returns true and fills the upload rates based on
+// the attributes of the autofilluploadresponse tag. On failure returns false.
+bool ParseAutofillUploadXml(std::string xml,
+                            double* positive_upload_rate,
+                            double* negative_upload_rate);
 
 }  // namespace autofill
 
diff --git a/components/autofill/core/browser/autofill_xml_parser_unittest.cc b/components/autofill/core/browser/autofill_xml_parser_unittest.cc
index 929b4759..8552b53 100644
--- a/components/autofill/core/browser/autofill_xml_parser_unittest.cc
+++ b/components/autofill/core/browser/autofill_xml_parser_unittest.cc
@@ -3,14 +3,15 @@
 // found in the LICENSE file.
 
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string_number_conversions.h"
+#include "components/autofill/core/browser/autofill_server_field_info.h"
 #include "components/autofill/core/browser/autofill_xml_parser.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/webrtc/libjingle/xmllite/xmlparser.h"
 
 namespace autofill {
 namespace {
@@ -21,13 +22,10 @@
   ~AutofillQueryXmlParserTest() override{};
 
  protected:
-  void ParseQueryXML(const std::string& xml, bool should_succeed) {
-    // Create a parser.
-    AutofillQueryXmlParser parse_handler(&field_infos_,
-                                         &upload_required_);
-    buzz::XmlParser parser(&parse_handler);
-    parser.Parse(xml.c_str(), xml.length(), true);
-    EXPECT_EQ(should_succeed, parse_handler.succeeded());
+  void ParseQueryXML(std::string xml, bool should_succeed) {
+    EXPECT_EQ(should_succeed,
+              ParseAutofillQueryXml(std::move(xml), &field_infos_,
+                                    &upload_required_));
   }
 
   std::vector<AutofillServerFieldInfo> field_infos_;
@@ -40,13 +38,9 @@
   ~AutofillUploadXmlParserTest() override{};
 
  protected:
-  void ParseUploadXML(const std::string& xml, bool should_succeed) {
-    // Create a parser.
-    AutofillUploadXmlParser parse_handler(&positive_, &negative_);
-    buzz::XmlParser parser(&parse_handler);
-    parser.Parse(xml.c_str(), xml.length(), true);
-
-    EXPECT_EQ(should_succeed, parse_handler.succeeded());
+  void ParseUploadXML(std::string xml, bool should_succeed) {
+    EXPECT_EQ(should_succeed,
+              ParseAutofillUploadXml(std::move(xml), &positive_, &negative_));
   }
 
   double positive_;
@@ -62,7 +56,7 @@
                     "<field autofilltype=\"2\" />"
                     "<field autofilltype=\"61\" defaultvalue=\"default\"/>"
                     "</autofillqueryresponse>";
-  ParseQueryXML(xml, true);
+  ParseQueryXML(std::move(xml), true);
 
   EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
   ASSERT_EQ(5U, field_infos_.size());
@@ -81,7 +75,7 @@
                     "<field autofilltype=\"0\" />"
                     "</autofillqueryresponse>";
 
-  ParseQueryXML(xml, true);
+  ParseQueryXML(std::move(xml), true);
 
   EXPECT_EQ(upload_required_, upload_required_);
   ASSERT_EQ(1U, field_infos_.size());
@@ -92,7 +86,7 @@
         "<field autofilltype=\"0\" />"
         "</autofillqueryresponse>";
 
-  ParseQueryXML(xml, true);
+  ParseQueryXML(std::move(xml), true);
 
   EXPECT_EQ(UPLOAD_NOT_REQUIRED, upload_required_);
   ASSERT_EQ(1U, field_infos_.size());
@@ -103,7 +97,7 @@
         "<field autofilltype=\"0\" />"
         "</autofillqueryresponse>";
 
-  ParseQueryXML(xml, true);
+  ParseQueryXML(std::move(xml), true);
 
   EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
   ASSERT_EQ(1U, field_infos_.size());
@@ -117,17 +111,14 @@
                     "<field/>"
                     "</autofillqueryresponse>";
 
-  ParseQueryXML(xml, false);
-
-  EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
-  EXPECT_EQ(0U, field_infos_.size());
+  ParseQueryXML(std::move(xml), false);
 
   // Test an incorrect Autofill type.
   xml = "<autofillqueryresponse>"
         "<field autofilltype=\"-1\"/>"
         "</autofillqueryresponse>";
 
-  ParseQueryXML(xml, true);
+  ParseQueryXML(std::move(xml), true);
 
   EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
   ASSERT_EQ(1U, field_infos_.size());
@@ -139,7 +130,7 @@
   xml = "<autofillqueryresponse><field autofilltype=\"" +
       base::IntToString(MAX_VALID_FIELD_TYPE) + "\"/></autofillqueryresponse>";
 
-  ParseQueryXML(xml, true);
+  ParseQueryXML(std::move(xml), true);
 
   EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
   ASSERT_EQ(1U, field_infos_.size());
@@ -152,8 +143,8 @@
         "<field autofilltype=\"No Type\"/>"
         "</autofillqueryresponse>";
 
-  // Parse fails but an entry is still added to field_infos_.
-  ParseQueryXML(xml, false);
+  // Unknown autofill type is handled gracefully.
+  ParseQueryXML(std::move(xml), true);
 
   EXPECT_EQ(USE_UPLOAD_RATES, upload_required_);
   ASSERT_EQ(1U, field_infos_.size());
@@ -176,26 +167,13 @@
                  "negativeuploadrate=\"0.3\"/>",
                  false);
 
-  EXPECT_DOUBLE_EQ(0, positive_);
-  EXPECT_DOUBLE_EQ(0.3, negative_);  // Partially parsed.
-  negative_ = 0;
-
   ParseUploadXML("<autofilluploadresponse positiveuploadrate=\"0.5\" "
                  "negativeuploadrate=\"0.3\"",
                  false);
 
-  EXPECT_DOUBLE_EQ(0, positive_);
-  EXPECT_DOUBLE_EQ(0, negative_);
-
   ParseUploadXML("bad data", false);
 
-  EXPECT_DOUBLE_EQ(0, positive_);
-  EXPECT_DOUBLE_EQ(0, negative_);
-
   ParseUploadXML(std::string(), false);
-
-  EXPECT_DOUBLE_EQ(0, positive_);
-  EXPECT_DOUBLE_EQ(0, negative_);
 }
 
 }  // namespace
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 1c7be13..351acbc 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -4,6 +4,7 @@
 
 #include "components/autofill/core/browser/form_structure.h"
 
+#include <map>
 #include <utility>
 
 #include "base/basictypes.h"
@@ -20,6 +21,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_server_field_info.h"
 #include "components/autofill/core/browser/autofill_type.h"
 #include "components/autofill/core/browser/autofill_xml_parser.h"
 #include "components/autofill/core/browser/field_types.h"
@@ -31,8 +33,8 @@
 #include "components/autofill/core/common/form_field_data_predictions.h"
 #include "components/rappor/rappor_service.h"
 #include "components/rappor/rappor_utils.h"
+#include "third_party/libxml/chromium/libxml_utils.h"
 #include "third_party/re2/re2/re2.h"
-#include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
 
 namespace autofill {
 namespace {
@@ -54,7 +56,6 @@
 const char kAttributeAutocomplete[] = "autocomplete";
 const char kAttributeLoginFormSignature[] = "loginformsignature";
 const char kClientVersion[] = "6.1.1715.1442/en (GGLL)";
-const char kXMLDeclaration[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
 const char kXMLElementAutofillQuery[] = "autofillquery";
 const char kXMLElementAutofillUpload[] = "autofillupload";
 const char kXMLElementFieldAssignments[] = "fieldassignments";
@@ -115,75 +116,86 @@
   return data_presence;
 }
 
-// Helper for |EncodeFormRequest()| and |EncodeFieldForUpload| that returns an
-// XmlElement for the given field in query xml, and also add it to the parent
-// XmlElement.
-buzz::XmlElement* EncodeFieldForQuery(const AutofillField& field,
-                                      buzz::XmlElement* parent) {
-  buzz::XmlElement* field_element = new buzz::XmlElement(
-      buzz::QName(kXMLElementField));
-  field_element->SetAttr(buzz::QName(kAttributeSignature),
-                         field.FieldSignature());
+// Assumes that |xml_writer| has just started an element with name
+// |kXMLElementField|, and adds some field attributes based on |field|. Returns
+// true on success, false on failure.
+bool EncodeFieldForQuery(const AutofillField& field, XmlWriter* xml_writer) {
+  if (!xml_writer->AddAttribute(kAttributeSignature, field.FieldSignature()))
+    return false;
   if (IsAutofillFieldMetadataEnabled()) {
     if (!field.name.empty()) {
-      field_element->SetAttr(buzz::QName(kAttributeName),
-                             base::UTF16ToUTF8(field.name));
+      if (!xml_writer->AddAttribute(kAttributeName,
+                                    base::UTF16ToUTF8(field.name)))
+        return false;
     }
-    field_element->SetAttr(buzz::QName(kAttributeControlType),
-                           field.form_control_type);
+    if (!xml_writer->AddAttribute(kAttributeControlType,
+                                  field.form_control_type))
+      return false;
     if (!field.label.empty()) {
       std::string truncated;
       base::TruncateUTF8ToByteSize(base::UTF16ToUTF8(field.label),
                                    kMaxFieldLabelNumChars, &truncated);
-      field_element->SetAttr(buzz::QName(kAttributeFieldLabel), truncated);
+      if (!xml_writer->AddAttribute(kAttributeFieldLabel, truncated))
+        return false;
     }
   }
-  parent->AddElement(field_element);
-  return field_element;
+  return true;
 }
 
-// Helper for |EncodeFormRequest()| that creates XmlElements for the given field
-// in upload xml, and also add them to the parent XmlElement.
-void EncodeFieldForUpload(const AutofillField& field,
-                          buzz::XmlElement* parent) {
+// Uses |xml_writer| to write one tag named |kXMLElementField| for each item in
+// |field.possible_types()|, and adds some field attributes based on |field|.
+// Returns true on success, false on failure.
+bool EncodeFieldForUpload(const AutofillField& field, XmlWriter* xml_writer) {
   // Don't upload checkable fields.
   if (field.is_checkable)
-    return;
+    return true;
 
-  ServerFieldTypeSet types = field.possible_types();
-  // |types| could be empty in unit-tests only.
+  const ServerFieldTypeSet& types = field.possible_types();
   for (const auto& field_type : types) {
-    // We use the same field elements as the query and add a few more below.
-    buzz::XmlElement* field_element = EncodeFieldForQuery(field, parent);
+    if (!xml_writer->StartElement(kXMLElementField))
+      return false;
+    // Add the same field elements as the query and a few more below.
+    if (!EncodeFieldForQuery(field, xml_writer))
+      return false;
 
     if (IsAutofillFieldMetadataEnabled() &&
         !field.autocomplete_attribute.empty()) {
-      field_element->SetAttr(buzz::QName(kAttributeAutocomplete),
-                             field.autocomplete_attribute);
+      if (!xml_writer->AddAttribute(kAttributeAutocomplete,
+                                    field.autocomplete_attribute))
+        return false;
     }
 
-    field_element->SetAttr(buzz::QName(kAttributeAutofillType),
-                           base::IntToString(field_type));
+    if (!xml_writer->AddAttribute(kAttributeAutofillType,
+                                  base::IntToString(field_type)))
+      return false;
+    if (!xml_writer->EndElement())
+      return false;
   }
+  return true;
 }
 
-// Helper for |EncodeFormRequest()| that creates XmlElements for the given field
-// in field assignments xml, and also add them to the parent XmlElement.
-void EncodeFieldForFieldAssignments(const AutofillField& field,
-                                    buzz::XmlElement* parent) {
-  ServerFieldTypeSet types = field.possible_types();
+// Uses |xml_writer| to write one tag named |kXMLElementFields| for each item in
+// |field.possible_types()|, and adds some field attributes based on |field|.
+// Returns true on success, false on failure.
+bool EncodeFieldForFieldAssignments(const AutofillField& field,
+                                    XmlWriter* xml_writer) {
+  const ServerFieldTypeSet& types = field.possible_types();
   for (const auto& field_type : types) {
-    buzz::XmlElement *field_element = new buzz::XmlElement(
-        buzz::QName(kXMLElementFields));
+    if (!xml_writer->StartElement(kXMLElementFields))
+      return false;
 
-    field_element->SetAttr(buzz::QName(kAttributeFieldID),
-                           field.FieldSignature());
-    field_element->SetAttr(buzz::QName(kAttributeFieldType),
-                           base::IntToString(field_type));
-    field_element->SetAttr(buzz::QName(kAttributeName),
-                           base::UTF16ToUTF8(field.name));
-    parent->AddElement(field_element);
+    if (!xml_writer->AddAttribute(kAttributeFieldID, field.FieldSignature()))
+      return false;
+    if (!xml_writer->AddAttribute(kAttributeFieldType,
+                                  base::IntToString(field_type)))
+      return false;
+    if (!xml_writer->AddAttribute(kAttributeName,
+                                  base::UTF16ToUTF8(field.name)))
+      return false;
+    if (!xml_writer->EndElement())
+      return false;
   }
+  return true;
 }
 
 // Returns |true| iff the |token| is a type hint for a contact field, as
@@ -442,49 +454,59 @@
     bool form_was_autofilled,
     const std::string& login_form_signature,
     std::string* encoded_xml) const {
+  DCHECK(encoded_xml);
   DCHECK(ShouldBeCrowdsourced());
 
   // Verify that |available_field_types| agrees with the possible field types we
   // are uploading.
   for (const AutofillField* field : *this) {
     for (const auto& type : field->possible_types()) {
-      DCHECK(type == UNKNOWN_TYPE ||
-             type == EMPTY_TYPE ||
+      DCHECK(type == UNKNOWN_TYPE || type == EMPTY_TYPE ||
              available_field_types.count(type));
     }
   }
 
   // Set up the <autofillupload> element and its attributes.
-  buzz::XmlElement autofill_request_xml(
-      (buzz::QName(kXMLElementAutofillUpload)));
-  autofill_request_xml.SetAttr(buzz::QName(kAttributeClientVersion),
-                               kClientVersion);
-  autofill_request_xml.SetAttr(buzz::QName(kAttributeFormSignature),
-                               FormSignature());
-  autofill_request_xml.SetAttr(buzz::QName(kAttributeAutofillUsed),
-                               form_was_autofilled ? "true" : "false");
-  autofill_request_xml.SetAttr(buzz::QName(kAttributeDataPresent),
-                               EncodeFieldTypes(available_field_types).c_str());
+  XmlWriter xml_writer;
+  xml_writer.StartWriting();
+  xml_writer.StopIndenting();
+  if (!xml_writer.StartElement(kXMLElementAutofillUpload))
+    return false;
+  if (!xml_writer.AddAttribute(kAttributeClientVersion, kClientVersion))
+    return false;
+  if (!xml_writer.AddAttribute(kAttributeFormSignature, FormSignature()))
+    return false;
+  if (!xml_writer.AddAttribute(kAttributeAutofillUsed,
+                               form_was_autofilled ? "true" : "false"))
+    return false;
+  if (!xml_writer.AddAttribute(kAttributeDataPresent,
+                               EncodeFieldTypes(available_field_types)))
+    return false;
   if (IsAutofillFieldMetadataEnabled()) {
-    autofill_request_xml.SetAttr(buzz::QName(kAttributeFormActionHostSignature),
-                                 Hash64Bit(target_url_.host()));
-    if(!form_name().empty()) {
-      autofill_request_xml.SetAttr(buzz::QName(kAttributeFormName),
-                                   base::UTF16ToUTF8(form_name()));
+    if (!xml_writer.AddAttribute(kAttributeFormActionHostSignature,
+                                 Hash64Bit(target_url_.host())))
+      return false;
+    if (!form_name().empty()) {
+      if (!xml_writer.AddAttribute(kAttributeFormName,
+                                   base::UTF16ToUTF8(form_name())))
+        return false;
     }
   }
 
   if (!login_form_signature.empty()) {
-    autofill_request_xml.SetAttr(buzz::QName(kAttributeLoginFormSignature),
-                                 login_form_signature);
+    if (!xml_writer.AddAttribute(kAttributeLoginFormSignature,
+                                 login_form_signature))
+      return false;
   }
 
-  if (!EncodeFormRequest(FormStructure::UPLOAD, &autofill_request_xml))
+  if (IsMalformed() || !EncodeFormRequest(FormStructure::UPLOAD, &xml_writer))
     return false;  // Malformed form, skip it.
+  if (!xml_writer.EndElement())
+    return false;
 
   // Obtain the XML structure as a string.
-  *encoded_xml = kXMLDeclaration;
-  *encoded_xml += autofill_request_xml.Str().c_str();
+  xml_writer.StopWriting();
+  *encoded_xml = xml_writer.GetWrittenString();
 
   // To enable this logging, run with the flag --vmodule="form_structure=2".
   VLOG(2) << "\n" << *encoded_xml;
@@ -495,21 +517,28 @@
 bool FormStructure::EncodeFieldAssignments(
     const ServerFieldTypeSet& available_field_types,
     std::string* encoded_xml) const {
+  DCHECK(encoded_xml);
   DCHECK(ShouldBeCrowdsourced());
 
   // Set up the <fieldassignments> element and its attributes.
-  buzz::XmlElement autofill_request_xml(
-      (buzz::QName(kXMLElementFieldAssignments)));
-  autofill_request_xml.SetAttr(buzz::QName(kAttributeFormSignature),
-                               FormSignature());
+  XmlWriter xml_writer;
+  xml_writer.StartWriting();
+  xml_writer.StopIndenting();
+  if (!xml_writer.StartElement(kXMLElementFieldAssignments))
+    return false;
+  if (!xml_writer.AddAttribute(kAttributeFormSignature, FormSignature()))
+    return false;
 
-  if (!EncodeFormRequest(FormStructure::FIELD_ASSIGNMENTS,
-                         &autofill_request_xml))
+  if (IsMalformed() ||
+      !EncodeFormRequest(FormStructure::FIELD_ASSIGNMENTS, &xml_writer)) {
     return false;  // Malformed form, skip it.
+  }
+  if (!xml_writer.EndElement())
+    return false;
 
   // Obtain the XML structure as a string.
-  *encoded_xml = kXMLDeclaration;
-  *encoded_xml += autofill_request_xml.Str().c_str();
+  xml_writer.StopWriting();
+  *encoded_xml = xml_writer.GetWrittenString();
 
   return true;
 }
@@ -521,37 +550,43 @@
     std::string* encoded_xml) {
   DCHECK(encoded_signatures);
   DCHECK(encoded_xml);
-  encoded_xml->clear();
   encoded_signatures->clear();
   encoded_signatures->reserve(forms.size());
 
   // Set up the <autofillquery> element and attributes.
-  buzz::XmlElement autofill_request_xml(
-      (buzz::QName(kXMLElementAutofillQuery)));
-  autofill_request_xml.SetAttr(buzz::QName(kAttributeClientVersion),
-                               kClientVersion);
+  XmlWriter xml_writer;
+  xml_writer.StartWriting();
+  xml_writer.StopIndenting();
+  if (!xml_writer.StartElement(kXMLElementAutofillQuery))
+    return false;
+  if (!xml_writer.AddAttribute(kAttributeClientVersion, kClientVersion))
+    return false;
 
   // Some badly formatted web sites repeat forms - detect that and encode only
   // one form as returned data would be the same for all the repeated forms.
   std::set<std::string> processed_forms;
-  for (const auto& it : forms) {
-    std::string signature(it->FormSignature());
+  for (const auto& form : forms) {
+    std::string signature(form->FormSignature());
     if (processed_forms.find(signature) != processed_forms.end())
       continue;
     processed_forms.insert(signature);
-    scoped_ptr<buzz::XmlElement> encompassing_xml_element(
-        new buzz::XmlElement(buzz::QName(kXMLElementForm)));
-    encompassing_xml_element->SetAttr(buzz::QName(kAttributeSignature),
-                                      signature);
+    if (form->IsMalformed())
+      continue;
+    if (!xml_writer.StartElement(kXMLElementForm))
+      return false;
+    if (!xml_writer.AddAttribute(kAttributeSignature, signature))
+      return false;
 
-    if (!it->EncodeFormRequest(FormStructure::QUERY,
-                               encompassing_xml_element.get())) {
-      continue;  // Malformed form, skip it.
-    }
+    if (!form->EncodeFormRequest(FormStructure::QUERY, &xml_writer))
+      continue;
 
-    autofill_request_xml.AddElement(encompassing_xml_element.release());
+    if (!xml_writer.EndElement())
+      return false;
+
     encoded_signatures->push_back(signature);
   }
+  if (!xml_writer.EndElement())
+    return false;
 
   if (!encoded_signatures->size())
     return false;
@@ -561,14 +596,14 @@
   // it ever resurfaces, re-add code here to set the attribute accordingly.
 
   // Obtain the XML structure as a string.
-  *encoded_xml = kXMLDeclaration;
-  *encoded_xml += autofill_request_xml.Str().c_str();
+  xml_writer.StopWriting();
+  *encoded_xml = xml_writer.GetWrittenString();
 
   return true;
 }
 
 // static
-void FormStructure::ParseQueryResponse(const std::string& response_xml,
+void FormStructure::ParseQueryResponse(std::string response_xml,
                                        const std::vector<FormStructure*>& forms,
                                        rappor::RapporService* rappor_service) {
   AutofillMetrics::LogServerQueryMetric(
@@ -577,11 +612,7 @@
   // Parse the field types from the server response to the query.
   std::vector<AutofillServerFieldInfo> field_infos;
   UploadRequired upload_required;
-  AutofillQueryXmlParser parse_handler(&field_infos,
-                                       &upload_required);
-  buzz::XmlParser parser(&parse_handler);
-  parser.Parse(response_xml.c_str(), response_xml.length(), true);
-  if (!parse_handler.succeeded())
+  if (!ParseAutofillQueryXml(response_xml, &field_infos, &upload_required))
     return;
 
   AutofillMetrics::LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED);
@@ -1027,11 +1058,9 @@
   return base::Uint64ToString(hash64);
 }
 
-bool FormStructure::EncodeFormRequest(
-    FormStructure::EncodeRequestType request_type,
-    buzz::XmlElement* encompassing_xml_element) const {
+bool FormStructure::IsMalformed() const {
   if (!field_count())  // Nothing to add.
-    return false;
+    return true;
 
   // Some badly formatted web sites repeat fields - limit number of fields to
   // 48, which is far larger than any valid form and XML still fits into 2K.
@@ -1039,22 +1068,33 @@
   // near certainly not valid/auto-fillable.
   const size_t kMaxFieldsOnTheForm = 48;
   if (field_count() > kMaxFieldsOnTheForm)
-    return false;
+    return true;
+  return false;
+}
 
+bool FormStructure::EncodeFormRequest(EncodeRequestType request_type,
+                                      XmlWriter* xml_writer) const {
+  DCHECK(!IsMalformed());
   // Add the child nodes for the form fields.
-  for (size_t index = 0; index < field_count(); ++index) {
-    const AutofillField* field = fields_[index];
+  for (const AutofillField* field : fields_) {
     switch (request_type) {
       case FormStructure::UPLOAD:
-        EncodeFieldForUpload(*field, encompassing_xml_element);
+        if (!EncodeFieldForUpload(*field, xml_writer))
+          return false;
         break;
       case FormStructure::QUERY:
         if (ShouldSkipField(*field))
           continue;
-        EncodeFieldForQuery(*field, encompassing_xml_element);
+        if (!xml_writer->StartElement(kXMLElementField))
+          return false;
+        if (!EncodeFieldForQuery(*field, xml_writer))
+          return false;
+        if (!xml_writer->EndElement())
+          return false;
         break;
       case FormStructure::FIELD_ASSIGNMENTS:
-        EncodeFieldForFieldAssignments(*field, encompassing_xml_element);
+        if (!EncodeFieldForFieldAssignments(*field, xml_writer))
+          return false;
         break;
     }
   }
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index fa7747b..670f1c23 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -17,9 +17,10 @@
 #include "components/autofill/core/browser/autofill_field.h"
 #include "components/autofill/core/browser/autofill_type.h"
 #include "components/autofill/core/browser/field_types.h"
-#include "components/autofill/core/common/web_element_descriptor.h"
 #include "url/gurl.h"
 
+class XmlWriter;
+
 enum UploadRequired {
   UPLOAD_NOT_REQUIRED,
   UPLOAD_REQUIRED,
@@ -83,7 +84,7 @@
   // Parses the field types from the server query response. |forms| must be the
   // same as the one passed to EncodeQueryRequest when constructing the query.
   // |rappor_service| may be null.
-  static void ParseQueryResponse(const std::string& response_xml,
+  static void ParseQueryResponse(std::string response_xml,
                                  const std::vector<FormStructure*>& forms,
                                  rappor::RapporService* rappor_service);
 
@@ -223,10 +224,14 @@
     FIELD_ASSIGNMENTS,
   };
 
-  // Adds form info to |encompassing_xml_element|. |request_type| indicates if
-  // it is a query or upload.
+  // Returns true if the form has no fields, or too many.
+  bool IsMalformed() const;
+
+  // Takes |xml_writer| and writes description for |fields_|, according to
+  // |request_type|. Returns false on failure, including when there are no
+  // fields, and true on success.
   bool EncodeFormRequest(EncodeRequestType request_type,
-                         buzz::XmlElement* encompassing_xml_element) const;
+                         XmlWriter* xml_writer) const;
 
   // Classifies each field in |fields_| into a logical section.
   // Sections are identified by the heuristic that a logical section should not
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 5aad585..b1acd4b 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -1510,7 +1510,8 @@
   std::vector<std::string> encoded_signatures;
   std::string encoded_xml;
   const char kSignature1[] = "11337937696949187602";
-  const char kResponse1[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+  const char kResponse1[] =
+      "<?xml version=\"1.0\"?>\n"
       "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
       "<form signature=\"11337937696949187602\">"
       "<field signature=\"412125936\" name=\"name_on_card\" type=\"text\""
@@ -1520,7 +1521,7 @@
       " label=\"Card Number\"/><field signature=\"747221617\""
       " name=\"expiration_month\" type=\"text\" label=\"Expiration Date\"/>"
       "<field signature=\"4108155786\" name=\"expiration_year\" type=\"text\""
-      " label=\"Expiration Year\"/></form></autofillquery>";
+      " label=\"Expiration Year\"/></form></autofillquery>\n";
   ASSERT_TRUE(FormStructure::EncodeQueryRequest(
       forms.get(), &encoded_signatures, &encoded_xml));
   ASSERT_EQ(1U, encoded_signatures.size());
@@ -1549,32 +1550,35 @@
   EXPECT_EQ(kSignature1, encoded_signatures[0]);
   const char kSignature2[] = "8308881815906226214";
   EXPECT_EQ(kSignature2, encoded_signatures[1]);
-  const char kResponse2[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-  "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
-  "<form signature=\"11337937696949187602\"><field signature=\"412125936\""
-  " name=\"name_on_card\" type=\"text\" label=\"Name on Card\"/>"
-  "<field signature=\"1917667676\" name=\"billing_address\" type=\"text\""
-  " label=\"Address\"/><field signature=\"2226358947\" name=\"card_number\""
-  " type=\"text\" label=\"Card Number\"/>"
-  "<field signature=\"747221617\" name=\"expiration_month\" type=\"text\""
-  " label=\"Expiration Date\"/>"
-  "<field signature=\"4108155786\" name=\"expiration_year\" type=\"text\""
-  " label=\"Expiration Year\"/></form>"
-  "<form signature=\"8308881815906226214\">"
-  "<field signature=\"412125936\" name=\"name_on_card\" type=\"text\""
-  " label=\"Name on Card\"/><field signature=\"1917667676\""
-  " name=\"billing_address\" type=\"text\" label=\"Address\"/>"
-  "<field signature=\"2226358947\" name=\"card_number\" type=\"text\""
-  " label=\"Card Number\"/><field signature=\"747221617\""
-  " name=\"expiration_month\" type=\"text\" label=\"Expiration Date\"/>"
-  "<field signature=\"4108155786\" name=\"expiration_year\" type=\"text\""
-  " label=\"Expiration Year\"/><field signature=\"509334676\" name=\"address\""
-  " type=\"text\" label=\"Address\"/><field signature=\"509334676\""
-  " name=\"address\" type=\"text\" label=\"Address\"/>"
-  "<field signature=\"509334676\" name=\"address\" type=\"text\""
-  " label=\"Address\"/><field signature=\"509334676\" name=\"address\""
-  " type=\"text\" label=\"Address\"/><field signature=\"509334676\""
-  " name=\"address\" type=\"text\" label=\"Address\"/></form></autofillquery>";
+  const char kResponse2[] =
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
+      "<form signature=\"11337937696949187602\"><field signature=\"412125936\""
+      " name=\"name_on_card\" type=\"text\" label=\"Name on Card\"/>"
+      "<field signature=\"1917667676\" name=\"billing_address\" type=\"text\""
+      " label=\"Address\"/><field signature=\"2226358947\" name=\"card_number\""
+      " type=\"text\" label=\"Card Number\"/>"
+      "<field signature=\"747221617\" name=\"expiration_month\" type=\"text\""
+      " label=\"Expiration Date\"/>"
+      "<field signature=\"4108155786\" name=\"expiration_year\" type=\"text\""
+      " label=\"Expiration Year\"/></form>"
+      "<form signature=\"8308881815906226214\">"
+      "<field signature=\"412125936\" name=\"name_on_card\" type=\"text\""
+      " label=\"Name on Card\"/><field signature=\"1917667676\""
+      " name=\"billing_address\" type=\"text\" label=\"Address\"/>"
+      "<field signature=\"2226358947\" name=\"card_number\" type=\"text\""
+      " label=\"Card Number\"/><field signature=\"747221617\""
+      " name=\"expiration_month\" type=\"text\" label=\"Expiration Date\"/>"
+      "<field signature=\"4108155786\" name=\"expiration_year\" type=\"text\""
+      " label=\"Expiration Year\"/><field signature=\"509334676\" "
+      "name=\"address\""
+      " type=\"text\" label=\"Address\"/><field signature=\"509334676\""
+      " name=\"address\" type=\"text\" label=\"Address\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\"/><field signature=\"509334676\" name=\"address\""
+      " type=\"text\" label=\"Address\"/><field signature=\"509334676\""
+      " name=\"address\" type=\"text\" "
+      "label=\"Address\"/></form></autofillquery>\n";
   EXPECT_EQ(kResponse2, encoded_xml);
 
   FormData malformed_form(form);
@@ -1599,8 +1603,6 @@
   bad_forms.push_back(new FormStructure(malformed_form));
   EXPECT_FALSE(FormStructure::EncodeQueryRequest(
       bad_forms.get(), &encoded_signatures, &encoded_xml));
-  EXPECT_EQ(0U, encoded_signatures.size());
-  EXPECT_EQ("", encoded_xml);
 }
 
 TEST_F(FormStructureTest, EncodeUploadRequest) {
@@ -1675,42 +1677,44 @@
   std::string encoded_xml;
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"8736493185895608956\" autofillused=\"false\""
-            " datapresent=\"144200030e\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"3763331450\" name=\"firstname\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"3\"/>"
-            "<field signature=\"3494530716\" name=\"lastname\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"5\"/>"
-            "<field signature=\"1029417091\" name=\"email\" type=\"email\""
-            " label=\"Email\" autofilltype=\"9\"/>"
-            "<field signature=\"466116101\" name=\"phone\" type=\"number\""
-            " label=\"Phone\" autofilltype=\"14\"/>"
-            "<field signature=\"2799270304\" name=\"country\""
-            " type=\"select-one\" label=\"Country\" autofilltype=\"36\"/>"
-            "</autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"8736493185895608956\" autofillused=\"false\""
+      " datapresent=\"144200030e\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"3763331450\" name=\"firstname\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"3\"/>"
+      "<field signature=\"3494530716\" name=\"lastname\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"5\"/>"
+      "<field signature=\"1029417091\" name=\"email\" type=\"email\""
+      " label=\"Email\" autofilltype=\"9\"/>"
+      "<field signature=\"466116101\" name=\"phone\" type=\"number\""
+      " label=\"Phone\" autofilltype=\"14\"/>"
+      "<field signature=\"2799270304\" name=\"country\""
+      " type=\"select-one\" label=\"Country\" autofilltype=\"36\"/>"
+      "</autofillupload>\n",
+      encoded_xml);
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"8736493185895608956\""
-            " autofillused=\"true\" datapresent=\"144200030e\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"3763331450\" name=\"firstname\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"3\"/>"
-            "<field signature=\"3494530716\" name=\"lastname\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"5\"/>"
-            "<field signature=\"1029417091\" name=\"email\" type=\"email\""
-            " label=\"Email\" autofilltype=\"9\"/>"
-            "<field signature=\"466116101\" name=\"phone\" type=\"number\""
-            " label=\"Phone\" autofilltype=\"14\"/>"
-            "<field signature=\"2799270304\" name=\"country\""
-            " type=\"select-one\" label=\"Country\" autofilltype=\"36\"/>"
-            "</autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"8736493185895608956\""
+      " autofillused=\"true\" datapresent=\"144200030e\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"3763331450\" name=\"firstname\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"3\"/>"
+      "<field signature=\"3494530716\" name=\"lastname\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"5\"/>"
+      "<field signature=\"1029417091\" name=\"email\" type=\"email\""
+      " label=\"Email\" autofilltype=\"9\"/>"
+      "<field signature=\"466116101\" name=\"phone\" type=\"number\""
+      " label=\"Phone\" autofilltype=\"14\"/>"
+      "<field signature=\"2799270304\" name=\"country\""
+      " type=\"select-one\" label=\"Country\" autofilltype=\"36\"/>"
+      "</autofillupload>\n",
+      encoded_xml);
 
   // Add 2 address fields - this should be still a valid form.
   for (size_t i = 0; i < 2; ++i) {
@@ -1732,38 +1736,39 @@
 
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"7816485729218079147\" autofillused=\"false\""
-            " datapresent=\"144200030e\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"3763331450\" name=\"firstname\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"3\"/>"
-            "<field signature=\"3494530716\" name=\"lastname\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"5\"/>"
-            "<field signature=\"1029417091\" name=\"email\" type=\"email\""
-            " label=\"Email\" autofilltype=\"9\"/>"
-            "<field signature=\"466116101\" name=\"phone\" type=\"number\""
-            " label=\"Phone\" autofilltype=\"14\"/>"
-            "<field signature=\"2799270304\" name=\"country\""
-            " type=\"select-one\" label=\"Country\" autofilltype=\"36\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"30\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"31\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"37\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"38\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"30\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"31\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"37\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"38\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"7816485729218079147\" autofillused=\"false\""
+      " datapresent=\"144200030e\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"3763331450\" name=\"firstname\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"3\"/>"
+      "<field signature=\"3494530716\" name=\"lastname\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"5\"/>"
+      "<field signature=\"1029417091\" name=\"email\" type=\"email\""
+      " label=\"Email\" autofilltype=\"9\"/>"
+      "<field signature=\"466116101\" name=\"phone\" type=\"number\""
+      " label=\"Phone\" autofilltype=\"14\"/>"
+      "<field signature=\"2799270304\" name=\"country\""
+      " type=\"select-one\" label=\"Country\" autofilltype=\"36\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"30\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"31\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"37\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"38\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"30\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"31\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"37\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"38\"/></autofillupload>\n",
+      encoded_xml);
 
   // Add 50 address fields - now the form is invalid, as it has too many fields.
   for (size_t i = 0; i < 50; ++i) {
@@ -1847,7 +1852,7 @@
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true,
                                                   "42", &encoded_xml));
   EXPECT_EQ(
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?><autofillupload "
+      "<?xml version=\"1.0\"?>\n<autofillupload "
       "clientversion=\"6.1.1715.1442/en (GGLL)\" "
       "formsignature=\"5810032074788446513\" autofillused=\"true\" "
       "datapresent=\"1440000000000000000802\" "
@@ -1863,7 +1868,7 @@
       "label=\"username\" autocomplete=\"email\" autofilltype=\"86\"/><field "
       "signature=\"2051817934\" name=\"password\" type=\"password\" "
       "label=\"password\" autocomplete=\"email\" "
-      "autofilltype=\"76\"/></autofillupload>",
+      "autofilltype=\"76\"/></autofillupload>\n",
       encoded_xml);
 }
 
@@ -1913,19 +1918,20 @@
   std::string encoded_xml;
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"14746822798145140279\" autofillused=\"true\""
-            " datapresent=\"1440\" actionsignature=\"15724779818122431245\">"
-            "<field signature=\"3763331450\" name=\"firstname\" type=\"text\""
-            " label=\"First Name\" autocomplete=\"given-name\""
-            " autofilltype=\"3\"/>"
-            "<field signature=\"3494530716\" name=\"lastname\" type=\"text\""
-            " label=\"Last Name\" autocomplete=\"family-name\""
-            " autofilltype=\"5\"/><field signature=\"1029417091\""
-            " name=\"email\" type=\"email\" label=\"Email\""
-            " autocomplete=\"email\" autofilltype=\"9\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"14746822798145140279\" autofillused=\"true\""
+      " datapresent=\"1440\" actionsignature=\"15724779818122431245\">"
+      "<field signature=\"3763331450\" name=\"firstname\" type=\"text\""
+      " label=\"First Name\" autocomplete=\"given-name\""
+      " autofilltype=\"3\"/>"
+      "<field signature=\"3494530716\" name=\"lastname\" type=\"text\""
+      " label=\"Last Name\" autocomplete=\"family-name\""
+      " autofilltype=\"5\"/><field signature=\"1029417091\""
+      " name=\"email\" type=\"email\" label=\"Email\""
+      " autocomplete=\"email\" autofilltype=\"9\"/></autofillupload>\n",
+      encoded_xml);
 }
 
 TEST_F(FormStructureTest, EncodeUploadRequest_WithLabels) {
@@ -1968,16 +1974,17 @@
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true,
                                                   std::string(), &encoded_xml));
   // Expected that the first field does not send the label but others do.
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"6949133589768631292\" autofillused=\"true\""
-            " datapresent=\"1440\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"1318412689\" type=\"text\" autofilltype=\"3\"/>"
-            "<field signature=\"1318412689\" type=\"text\" label=\"Last Name\""
-            " autofilltype=\"5\"/><field signature=\"1318412689\" type=\"text\""
-            " label=\"Email\" autofilltype=\"9\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"6949133589768631292\" autofillused=\"true\""
+      " datapresent=\"1440\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"1318412689\" type=\"text\" autofilltype=\"3\"/>"
+      "<field signature=\"1318412689\" type=\"text\" label=\"Last Name\""
+      " autofilltype=\"5\"/><field signature=\"1318412689\" type=\"text\""
+      " label=\"Email\" autofilltype=\"9\"/></autofillupload>\n",
+      encoded_xml);
 }
 
 // Test that the form name is sent in the upload request.
@@ -2019,15 +2026,16 @@
   std::string encoded_xml;
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?><autofillupload"
-            " clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"2345951786066580868\" autofillused=\"true\""
-            " datapresent=\"1440\" actionsignature=\"15724779818122431245\""
-            " formname=\"myform\"><field signature=\"1318412689\" type=\"text\""
-            " autofilltype=\"3\"/><field signature=\"1318412689\" type=\"text\""
-            " autofilltype=\"5\"/><field signature=\"1318412689\" type=\"text\""
-            " autofilltype=\"9\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n<autofillupload"
+      " clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"2345951786066580868\" autofillused=\"true\""
+      " datapresent=\"1440\" actionsignature=\"15724779818122431245\""
+      " formname=\"myform\"><field signature=\"1318412689\" type=\"text\""
+      " autofilltype=\"3\"/><field signature=\"1318412689\" type=\"text\""
+      " autofilltype=\"5\"/><field signature=\"1318412689\" type=\"text\""
+      " autofilltype=\"9\"/></autofillupload>\n",
+      encoded_xml);
 }
 
 TEST_F(FormStructureTest, EncodeUploadRequestPartialMetadata) {
@@ -2075,18 +2083,19 @@
   std::string encoded_xml;
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"13043654279838250996\" autofillused=\"true\""
-            " datapresent=\"1440\" actionsignature=\"15724779818122431245\">"
-            "<field signature=\"1318412689\" type=\"text\" autofilltype=\"3\"/>"
-            "<field signature=\"3494530716\" name=\"lastname\" type=\"text\""
-            " label=\"Last Name\" autocomplete=\"family-name\""
-            " autofilltype=\"5\"/>"
-            "<field signature=\"1545468175\" name=\"lastname\" type=\"email\""
-            " label=\"Email\" autocomplete=\"email\" autofilltype=\"9\"/>"
-            "</autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"13043654279838250996\" autofillused=\"true\""
+      " datapresent=\"1440\" actionsignature=\"15724779818122431245\">"
+      "<field signature=\"1318412689\" type=\"text\" autofilltype=\"3\"/>"
+      "<field signature=\"3494530716\" name=\"lastname\" type=\"text\""
+      " label=\"Last Name\" autocomplete=\"family-name\""
+      " autofilltype=\"5\"/>"
+      "<field signature=\"1545468175\" name=\"lastname\" type=\"email\""
+      " label=\"Email\" autocomplete=\"email\" autofilltype=\"9\"/>"
+      "</autofillupload>\n",
+      encoded_xml);
 }
 
 // Sending field metadata to the server is disabled.
@@ -2138,14 +2147,15 @@
   std::string encoded_xml;
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"14746822798145140279\" autofillused=\"true\""
-            " datapresent=\"1440\"><field signature=\"3763331450\""
-            " autofilltype=\"3\"/><field signature=\"3494530716\""
-            " autofilltype=\"5\"/><field signature=\"1029417091\""
-            " autofilltype=\"9\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"14746822798145140279\" autofillused=\"true\""
+      " datapresent=\"1440\"><field signature=\"3763331450\""
+      " autofilltype=\"3\"/><field signature=\"3494530716\""
+      " autofilltype=\"5\"/><field signature=\"1029417091\""
+      " autofilltype=\"9\"/></autofillupload>\n",
+      encoded_xml);
 }
 
 TEST_F(FormStructureTest, EncodeFieldAssignments) {
@@ -2221,7 +2231,7 @@
   EXPECT_TRUE(form_structure->EncodeFieldAssignments(
       available_field_types, &encoded_xml));
   EXPECT_EQ(
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+      "<?xml version=\"1.0\"?>\n"
       "<fieldassignments formsignature=\"8736493185895608956\">"
       "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>"
       "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>"
@@ -2229,7 +2239,7 @@
       "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>"
       "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>"
       "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>"
-      "</fieldassignments>",
+      "</fieldassignments>\n",
       encoded_xml);
 
   // Add 2 address fields - this should be still a valid form.
@@ -2253,7 +2263,7 @@
   EXPECT_TRUE(form_structure->EncodeFieldAssignments(
       available_field_types, &encoded_xml));
   EXPECT_EQ(
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+      "<?xml version=\"1.0\"?>\n"
       "<fieldassignments formsignature=\"7816485729218079147\">"
       "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>"
       "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>"
@@ -2269,7 +2279,7 @@
       "<fields fieldid=\"509334676\" fieldtype=\"31\" name=\"address\"/>"
       "<fields fieldid=\"509334676\" fieldtype=\"37\" name=\"address\"/>"
       "<fields fieldid=\"509334676\" fieldtype=\"38\" name=\"address\"/>"
-      "</fieldassignments>",
+      "</fieldassignments>\n",
       encoded_xml);
 }
 
@@ -2308,17 +2318,18 @@
   std::string encoded_xml;
   EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
                                                  std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"6402244543831589061\" autofillused=\"false\""
-            " datapresent=\"\" actionsignature=\"15724779818122431245\">"
-            "<field signature=\"1089846351\" name=\"first\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"1\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"1\"/>"
-            "<field signature=\"420638584\" name=\"email\" type=\"text\""
-            " label=\"Email\" autofilltype=\"1\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"6402244543831589061\" autofillused=\"false\""
+      " datapresent=\"\" actionsignature=\"15724779818122431245\">"
+      "<field signature=\"1089846351\" name=\"first\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"1\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"1\"/>"
+      "<field signature=\"420638584\" name=\"email\" type=\"text\""
+      " label=\"Email\" autofilltype=\"1\"/></autofillupload>\n",
+      encoded_xml);
 
   // Only a few types available.
   // datapresent should be "1540000240" == trimmmed(0x1540000240000000) ==
@@ -2340,18 +2351,19 @@
 
   EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
                                                  std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"6402244543831589061\" autofillused=\"false\""
-            " datapresent=\"1540000240\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"1089846351\" name=\"first\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"1\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"1\"/>"
-            "<field signature=\"420638584\" name=\"email\" type=\"text\""
-            " label=\"Email\" autofilltype=\"1\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"6402244543831589061\" autofillused=\"false\""
+      " datapresent=\"1540000240\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"1089846351\" name=\"first\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"1\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"1\"/>"
+      "<field signature=\"420638584\" name=\"email\" type=\"text\""
+      " label=\"Email\" autofilltype=\"1\"/></autofillupload>\n",
+      encoded_xml);
 
   // All supported non-credit card types available.
   // datapresent should be "1f7e000378000008" == trimmmed(0x1f7e000378000008) ==
@@ -2397,18 +2409,19 @@
 
   EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
                                                  std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"6402244543831589061\" autofillused=\"false\""
-            " datapresent=\"1f7e000378000008\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"1089846351\" name=\"first\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"1\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"1\"/>"
-            "<field signature=\"420638584\" name=\"email\" type=\"text\""
-            " label=\"Email\" autofilltype=\"1\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"6402244543831589061\" autofillused=\"false\""
+      " datapresent=\"1f7e000378000008\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"1089846351\" name=\"first\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"1\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"1\"/>"
+      "<field signature=\"420638584\" name=\"email\" type=\"text\""
+      " label=\"Email\" autofilltype=\"1\"/></autofillupload>\n",
+      encoded_xml);
 
   // All supported credit card types available.
   // datapresent should be "0000000000001fc0" == trimmmed(0x0000000000001fc0) ==
@@ -2432,18 +2445,19 @@
 
   EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
                                                  std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"6402244543831589061\" autofillused=\"false\""
-            " datapresent=\"0000000000001fc0\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"1089846351\" name=\"first\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"1\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"1\"/>"
-            "<field signature=\"420638584\" name=\"email\" type=\"text\""
-            " label=\"Email\" autofilltype=\"1\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"6402244543831589061\" autofillused=\"false\""
+      " datapresent=\"0000000000001fc0\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"1089846351\" name=\"first\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"1\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"1\"/>"
+      "<field signature=\"420638584\" name=\"email\" type=\"text\""
+      " label=\"Email\" autofilltype=\"1\"/></autofillupload>\n",
+      encoded_xml);
 
   // All supported types available.
   // datapresent should be "1f7e000378001fc8" == trimmmed(0x1f7e000378001fc8) ==
@@ -2503,18 +2517,19 @@
 
   EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
                                                  std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"6402244543831589061\" autofillused=\"false\""
-            " datapresent=\"1f7e000378001fc8\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"1089846351\" name=\"first\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"1\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"1\"/>"
-            "<field signature=\"420638584\" name=\"email\" type=\"text\""
-            " label=\"Email\" autofilltype=\"1\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"6402244543831589061\" autofillused=\"false\""
+      " datapresent=\"1f7e000378001fc8\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"1089846351\" name=\"first\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"1\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"1\"/>"
+      "<field signature=\"420638584\" name=\"email\" type=\"text\""
+      " label=\"Email\" autofilltype=\"1\"/></autofillupload>\n",
+      encoded_xml);
 }
 
 TEST_F(FormStructureTest, CheckMultipleTypes) {
@@ -2581,64 +2596,67 @@
   // Now we matched both fields singularly.
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"18062476096658145866\" autofillused=\"false\""
-            " datapresent=\"1440000360000008\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"420638584\" name=\"email\" type=\"text\""
-            " label=\"email\" autofilltype=\"9\"/>"
-            "<field signature=\"1089846351\" name=\"first\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"3\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"5\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"30\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"18062476096658145866\" autofillused=\"false\""
+      " datapresent=\"1440000360000008\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"420638584\" name=\"email\" type=\"text\""
+      " label=\"email\" autofilltype=\"9\"/>"
+      "<field signature=\"1089846351\" name=\"first\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"3\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"5\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"30\"/></autofillupload>\n",
+      encoded_xml);
   // Match third field as both first and last.
   possible_field_types[2].insert(NAME_FIRST);
   form_structure->field(2)->set_possible_types(possible_field_types[2]);
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"18062476096658145866\" autofillused=\"false\""
-            " datapresent=\"1440000360000008\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"420638584\" name=\"email\" type=\"text\""
-            " label=\"email\" autofilltype=\"9\"/>"
-            "<field signature=\"1089846351\" name=\"first\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"3\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"3\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"5\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"30\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"18062476096658145866\" autofillused=\"false\""
+      " datapresent=\"1440000360000008\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"420638584\" name=\"email\" type=\"text\""
+      " label=\"email\" autofilltype=\"9\"/>"
+      "<field signature=\"1089846351\" name=\"first\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"3\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"3\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"5\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"30\"/></autofillupload>\n",
+      encoded_xml);
   possible_field_types[3].insert(ADDRESS_HOME_LINE2);
   form_structure->field(form_structure->field_count() - 1)->set_possible_types(
       possible_field_types[form_structure->field_count() - 1]);
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"18062476096658145866\" autofillused=\"false\""
-            " datapresent=\"1440000360000008\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"420638584\" name=\"email\" type=\"text\""
-            " label=\"email\" autofilltype=\"9\"/>"
-            "<field signature=\"1089846351\" name=\"first\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"3\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"3\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"5\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"30\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"31\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"18062476096658145866\" autofillused=\"false\""
+      " datapresent=\"1440000360000008\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"420638584\" name=\"email\" type=\"text\""
+      " label=\"email\" autofilltype=\"9\"/>"
+      "<field signature=\"1089846351\" name=\"first\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"3\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"3\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"5\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"30\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"31\"/></autofillupload>\n",
+      encoded_xml);
   possible_field_types[3].clear();
   possible_field_types[3].insert(ADDRESS_HOME_LINE1);
   possible_field_types[3].insert(COMPANY_NAME);
@@ -2646,24 +2664,25 @@
       possible_field_types[form_structure->field_count() - 1]);
   EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
                                                   std::string(), &encoded_xml));
-  EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
-            " formsignature=\"18062476096658145866\" autofillused=\"false\""
-            " datapresent=\"1440000360000008\""
-            " actionsignature=\"15724779818122431245\">"
-            "<field signature=\"420638584\" name=\"email\" type=\"text\""
-            " label=\"email\" autofilltype=\"9\"/>"
-            "<field signature=\"1089846351\" name=\"first\" type=\"text\""
-            " label=\"First Name\" autofilltype=\"3\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"3\"/>"
-            "<field signature=\"2404144663\" name=\"last\" type=\"text\""
-            " label=\"Last Name\" autofilltype=\"5\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"30\"/>"
-            "<field signature=\"509334676\" name=\"address\" type=\"text\""
-            " label=\"Address\" autofilltype=\"60\"/></autofillupload>",
-            encoded_xml);
+  EXPECT_EQ(
+      "<?xml version=\"1.0\"?>\n"
+      "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
+      " formsignature=\"18062476096658145866\" autofillused=\"false\""
+      " datapresent=\"1440000360000008\""
+      " actionsignature=\"15724779818122431245\">"
+      "<field signature=\"420638584\" name=\"email\" type=\"text\""
+      " label=\"email\" autofilltype=\"9\"/>"
+      "<field signature=\"1089846351\" name=\"first\" type=\"text\""
+      " label=\"First Name\" autofilltype=\"3\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"3\"/>"
+      "<field signature=\"2404144663\" name=\"last\" type=\"text\""
+      " label=\"Last Name\" autofilltype=\"5\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"30\"/>"
+      "<field signature=\"509334676\" name=\"address\" type=\"text\""
+      " label=\"Address\" autofilltype=\"60\"/></autofillupload>\n",
+      encoded_xml);
 }
 
 TEST_F(FormStructureTest, CheckFormSignature) {
@@ -2789,13 +2808,14 @@
   std::string encoded_xml;
 
   const char kSignature[] = "18006745212084723782";
-  const char kResponse[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+  const char kResponse[] =
+      "<?xml version=\"1.0\"?>\n"
       "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
       "<form signature=\"18006745212084723782\">"
       "<field signature=\"239111655\" name=\"username\" type=\"text\""
       " label=\"username\"/>"
       "<field signature=\"420638584\" name=\"email\" type=\"text\"/>"
-      "</form></autofillquery>";
+      "</form></autofillquery>\n";
   ASSERT_TRUE(FormStructure::EncodeQueryRequest(
       forms.get(), &encoded_signatures, &encoded_xml));
   ASSERT_EQ(1U, encoded_signatures.size());
@@ -2830,14 +2850,15 @@
   std::vector<std::string> encoded_signatures;
   std::string encoded_xml;
 
-  const char kRequest[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+  const char kRequest[] =
+      "<?xml version=\"1.0\"?>\n"
       "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
       "<form signature=\"13906559713264665730\">"
       "<field signature=\"239111655\" name=\"username\" type=\"text\"/>"
       "<field signature=\"420638584\" name=\"email\" type=\"text\""
       " label=\"Enter your Email address\"/>"
       "<field signature=\"2051817934\" name=\"password\" type=\"password\""
-      " label=\"Enter your Password\"/></form></autofillquery>";
+      " label=\"Enter your Password\"/></form></autofillquery>\n";
   EXPECT_TRUE(FormStructure::EncodeQueryRequest(
       forms.get(), &encoded_signatures, &encoded_xml));
   EXPECT_EQ(kRequest, encoded_xml);
@@ -2876,7 +2897,7 @@
   std::string encoded_xml;
 
   const char kRequest[] =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+      "<?xml version=\"1.0\"?>\n"
       "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
       "<form signature=\"13906559713264665730\">"
       "<field signature=\"239111655\" name=\"username\" type=\"text\"/>"
@@ -2886,7 +2907,7 @@
       " That's What Marketers Do! We Know That Your Email Address Has The"
       " Poss\"/>"
       "<field signature=\"2051817934\" name=\"password\" type=\"password\""
-      " label=\"Enter your Password\"/></form></autofillquery>";
+      " label=\"Enter your Password\"/></form></autofillquery>\n";
   EXPECT_TRUE(FormStructure::EncodeQueryRequest(
       forms.get(), &encoded_signatures, &encoded_xml));
   EXPECT_EQ(kRequest, encoded_xml);
@@ -2918,12 +2939,13 @@
   std::string encoded_xml;
 
   const char kSignature[] = "16416961345885087496";
-  const char kResponse[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+  const char kResponse[] =
+      "<?xml version=\"1.0\"?>\n"
       "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
       "<form signature=\"16416961345885087496\">"
       "<field signature=\"239111655\" name=\"username\" type=\"text\""
       " label=\"username\"/><field signature=\"1318412689\" type=\"text\"/>"
-      "</form></autofillquery>";
+      "</form></autofillquery>\n";
   ASSERT_TRUE(FormStructure::EncodeQueryRequest(
       forms.get(), &encoded_signatures, &encoded_xml));
   ASSERT_EQ(1U, encoded_signatures.size());
@@ -2958,12 +2980,13 @@
   std::string encoded_xml;
 
   const char kSignature[] = "7635954436925888745";
-  const char kResponse[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+  const char kResponse[] =
+      "<?xml version=\"1.0\"?>\n"
       "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
       "<form signature=\"7635954436925888745\">"
       "<field signature=\"239111655\"/>"
       "<field signature=\"3654076265\"/>"
-      "</form></autofillquery>";
+      "</form></autofillquery>\n";
   ASSERT_TRUE(FormStructure::EncodeQueryRequest(
       forms.get(), &encoded_signatures, &encoded_xml));
   ASSERT_EQ(1U, encoded_signatures.size());
diff --git a/components/autofill/core/common/BUILD.gn b/components/autofill/core/common/BUILD.gn
index 9a53fe24..ca36439 100644
--- a/components/autofill/core/common/BUILD.gn
+++ b/components/autofill/core/common/BUILD.gn
@@ -34,8 +34,6 @@
     "password_generation_util.h",
     "save_password_progress_logger.cc",
     "save_password_progress_logger.h",
-    "web_element_descriptor.cc",
-    "web_element_descriptor.h",
   ]
 
   deps = [
diff --git a/components/autofill/core/common/web_element_descriptor.cc b/components/autofill/core/common/web_element_descriptor.cc
deleted file mode 100644
index 76e0543..0000000
--- a/components/autofill/core/common/web_element_descriptor.cc
+++ /dev/null
@@ -1,12 +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/autofill/core/common/web_element_descriptor.h"
-
-namespace autofill {
-
-WebElementDescriptor::WebElementDescriptor()
-  : retrieval_method(NONE) {}
-
-}  // namespace autofill
diff --git a/components/autofill/core/common/web_element_descriptor.h b/components/autofill/core/common/web_element_descriptor.h
deleted file mode 100644
index 6f41cbb..0000000
--- a/components/autofill/core/common/web_element_descriptor.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_AUTOFILL_CORE_COMMON_WEB_ELEMENT_DESCRIPTOR_H_
-#define COMPONENTS_AUTOFILL_CORE_COMMON_WEB_ELEMENT_DESCRIPTOR_H_
-
-#include <string>
-
-namespace autofill {
-
-// Holds information that can be used to retrieve an element.
-struct WebElementDescriptor {
-  enum RetrievalMethod {
-    CSS_SELECTOR,
-    ID,
-    NONE,
-  };
-
-  WebElementDescriptor();
-
-  // Information to retrieve element with.
-  std::string descriptor;
-
-  // Which retrieval method to use.
-  RetrievalMethod retrieval_method;
-};
-
-}  // namespace autofill
-
-#endif  // COMPONENTS_AUTOFILL_CORE_COMMON_WEB_ELEMENT_DESCRIPTOR_H_
diff --git a/components/drive/service/drive_api_service.cc b/components/drive/service/drive_api_service.cc
index 2f47fe6..446503a 100644
--- a/components/drive/service/drive_api_service.cc
+++ b/components/drive/service/drive_api_service.cc
@@ -248,11 +248,12 @@
     base::SequencedTaskRunner* blocking_task_runner,
     const GURL& base_url,
     const GURL& base_download_url,
+    const GURL& base_thumbnail_url,
     const std::string& custom_user_agent)
     : oauth2_token_service_(oauth2_token_service),
       url_request_context_getter_(url_request_context_getter),
       blocking_task_runner_(blocking_task_runner),
-      url_generator_(base_url, base_download_url),
+      url_generator_(base_url, base_download_url, base_thumbnail_url),
       custom_user_agent_(custom_user_agent) {
 }
 
diff --git a/components/drive/service/drive_api_service.h b/components/drive/service/drive_api_service.h
index 22bb7d4..374edc0 100644
--- a/components/drive/service/drive_api_service.h
+++ b/components/drive/service/drive_api_service.h
@@ -93,6 +93,8 @@
   // |base_url| is used to generate URLs for communication with the drive API.
   // |base_download_url| is used to generate URLs for downloading file from the
   // drive API.
+  // |base_thumbnail_url| is used to generate URLs for downloading thumbnail
+  // from image server.
   // |custom_user_agent| will be used for the User-Agent header in HTTP
   // requests issues through the service if the value is not empty.
   DriveAPIService(
@@ -101,6 +103,7 @@
       base::SequencedTaskRunner* blocking_task_runner,
       const GURL& base_url,
       const GURL& base_download_url,
+      const GURL& base_thumbnail_url,
       const std::string& custom_user_agent);
   ~DriveAPIService() override;
 
diff --git a/components/drive/service/drive_api_service_unittest.cc b/components/drive/service/drive_api_service_unittest.cc
index 6655e68..c6a4e2f 100644
--- a/components/drive/service/drive_api_service_unittest.cc
+++ b/components/drive/service/drive_api_service_unittest.cc
@@ -36,7 +36,8 @@
 
 TEST(DriveAPIServiceTest, BatchRequestConfiguratorWithAuthFailure) {
   const GURL test_base_url("http://localhost/");
-  google_apis::DriveApiUrlGenerator url_generator(test_base_url, test_base_url);
+  google_apis::DriveApiUrlGenerator url_generator(
+      test_base_url, test_base_url, test_base_url);
   scoped_refptr<base::TestSimpleTaskRunner> task_runner =
       new base::TestSimpleTaskRunner();
   scoped_refptr<net::TestURLRequestContextGetter> request_context_getter =
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index e8a0e60..f1983af 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -112,6 +112,8 @@
 void ShellSurface::OnSurfaceCommit() {
   if (widget_ || show_state_ == ui::SHOW_STATE_END) {
     surface_->CommitSurfaceHierarchy();
+    if (widget_)
+      widget_->SetSize(widget_->non_client_view()->GetPreferredSize());
     return;
   }
 
diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc
index 6ade2840..d04da9e 100644
--- a/components/exo/shell_surface_unittest.cc
+++ b/components/exo/shell_surface_unittest.cc
@@ -3,11 +3,14 @@
 // found in the LICENSE file.
 
 #include "base/strings/utf_string_conversions.h"
+#include "components/exo/buffer.h"
 #include "components/exo/shell_surface.h"
 #include "components/exo/surface.h"
 #include "components/exo/test/exo_test_base.h"
 #include "components/exo/test/exo_test_helper.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/khronos/GLES2/gl2.h"
+#include "ui/views/widget/widget.h"
 
 namespace exo {
 namespace {
@@ -15,11 +18,30 @@
 using ShellSurfaceTest = test::ExoTestBase;
 
 TEST_F(ShellSurfaceTest, Show) {
+  gfx::Size small_buffer_size(64, 64);
+  scoped_ptr<Buffer> small_buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(small_buffer_size),
+                 GL_TEXTURE_2D));
+  gfx::Size large_buffer_size(256, 256);
+  scoped_ptr<Buffer> large_buffer(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(large_buffer_size),
+                 GL_TEXTURE_2D));
   scoped_ptr<Surface> surface(new Surface);
   scoped_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
 
   shell_surface->Show();
+  surface->Attach(small_buffer.get());
   surface->Commit();
+  ASSERT_TRUE(shell_surface->GetWidget());
+  EXPECT_EQ(
+      small_buffer_size.ToString(),
+      shell_surface->GetWidget()->GetWindowBoundsInScreen().size().ToString());
+
+  surface->Attach(large_buffer.get());
+  surface->Commit();
+  EXPECT_EQ(
+      large_buffer_size.ToString(),
+      shell_surface->GetWidget()->GetWindowBoundsInScreen().size().ToString());
 }
 
 TEST_F(ShellSurfaceTest, SetToplevel) {
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc
index e38cd6c..96d43fc 100644
--- a/components/exo/surface_unittest.cc
+++ b/components/exo/surface_unittest.cc
@@ -10,7 +10,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/khronos/GLES2/gl2.h"
 #include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/views/test/widget_test.h"
 
 namespace exo {
 namespace {
diff --git a/components/flags_ui/flags_state.cc b/components/flags_ui/flags_state.cc
index b7345b2..9583d9e5 100644
--- a/components/flags_ui/flags_state.cc
+++ b/components/flags_ui/flags_state.cc
@@ -73,6 +73,7 @@
     {kOsCrOS, "Chrome OS"},
     {kOsAndroid, "Android"},
     {kOsCrOSOwnerOnly, "Chrome OS (owner only)"},
+    {kOsIos, "iOS"},
 };
 
 // Adds a |StringValue| to |list| for each platform where |bitmask| indicates
@@ -427,6 +428,10 @@
       supported = true;
     }
 #endif
+#if defined(OS_IOS)
+    if (access == kAppleReviewAccessToFlags)
+      supported = ((entry.supported_platforms & kOsIosAppleReview) != 0);
+#endif
     if (supported)
       supported_entries->Append(data);
     else
@@ -436,7 +441,9 @@
 
 // static
 int FlagsState::GetCurrentPlatform() {
-#if defined(OS_MACOSX)
+#if defined(OS_IOS)  // Needs to be before the OS_MACOSX check.
+  return kOsIos;
+#elif defined(OS_MACOSX)
   return kOsMac;
 #elif defined(OS_WIN)
   return kOsWin;
diff --git a/components/flags_ui/flags_state.h b/components/flags_ui/flags_state.h
index 8f2a19ff..f1e91dc 100644
--- a/components/flags_ui/flags_state.h
+++ b/components/flags_ui/flags_state.h
@@ -30,7 +30,9 @@
   kOsLinux = 1 << 2,
   kOsCrOS = 1 << 3,
   kOsAndroid = 1 << 4,
-  kOsCrOSOwnerOnly = 1 << 5
+  kOsCrOSOwnerOnly = 1 << 5,
+  kOsIos = 1 << 6,
+  kOsIosAppleReview = 1 << 7,
 };
 
 // A flag controlling the behavior of the |ConvertFlagsToSwitches| function -
@@ -41,7 +43,10 @@
 // that influence the whole machine and can be said by the admin only. This flag
 // is relevant for ChromeOS for now only and dictates whether entries marked
 // with the |kOsCrOSOwnerOnly| label should be enabled in the UI or not.
-enum FlagAccess { kGeneralAccessFlagsOnly, kOwnerAccessToFlags };
+// On iOS, |kAppleReviewAccessToFlags| indicates that the flags shown should
+// be the ones marked for Apple review (which otherwise will not be shown).
+enum FlagAccess { kGeneralAccessFlagsOnly, kOwnerAccessToFlags,
+                  kAppleReviewAccessToFlags };
 
 // Stores and encapsulates the little state that about:flags has.
 class FlagsState {
diff --git a/components/html_viewer/html_frame.cc b/components/html_viewer/html_frame.cc
index c58f5e20..8050f145 100644
--- a/components/html_viewer/html_frame.cc
+++ b/components/html_viewer/html_frame.cc
@@ -678,11 +678,10 @@
   SetWindow(window);
   SetReplicatedFrameStateFromClientProperties(properties, &state_);
   blink::WebLocalFrame* local_web_frame =
-      blink::WebLocalFrame::create(state_.tree_scope, this);
-  local_web_frame->initializeToReplaceRemoteFrame(
-      web_frame_->toWebRemoteFrame(), state_.name, state_.sandbox_flags,
-      // TODO(lazyboy): Figure out replicating WebFrameOwnerProperties.
-      blink::WebFrameOwnerProperties());
+      blink::WebLocalFrame::createProvisional(
+          this, web_frame_->toWebRemoteFrame(), state_.sandbox_flags,
+          // TODO(lazyboy): Figure out replicating WebFrameOwnerProperties.
+          blink::WebFrameOwnerProperties());
   // The swap() ends up calling to frameDetached() and deleting the old.
   web_frame_->swap(local_web_frame);
   web_frame_ = local_web_frame;
diff --git a/components/mus/public/interfaces/window_tree.mojom b/components/mus/public/interfaces/window_tree.mojom
index f0c619f..ea172b3 100644
--- a/components/mus/public/interfaces/window_tree.mojom
+++ b/components/mus/public/interfaces/window_tree.mojom
@@ -44,6 +44,8 @@
 // embedded apps representation.
 enum SurfaceType {
   // Only the owner of a window may obtain this surface.
+  // The window manager can change the offset of this by way of
+  // SetUnderlaySurfaceOffsetAndExtendedHitArea().
   UNDERLAY,
 
   // Only the embedded app may obtain this surface. If an app is not embedded
diff --git a/components/mus/public/interfaces/window_tree_host.mojom b/components/mus/public/interfaces/window_tree_host.mojom
index 864b577..3209bdab 100644
--- a/components/mus/public/interfaces/window_tree_host.mojom
+++ b/components/mus/public/interfaces/window_tree_host.mojom
@@ -33,6 +33,17 @@
   RemoveActivationParent(uint32 window_id);
 
   ActivateNextWindow();
+
+  // Sets the underlay surface offset for the specified window and additional
+  // hit area. The underlay surface is drawn at the bounds of the window minus
+  // the offset. The hit area is extended from the bounds of the window by
+  // |hit_area|.
+  // TODO(sky): pull this into the WindowTree API exposed for the
+  // windowmanager.
+  SetUnderlaySurfaceOffsetAndExtendedHitArea(uint32 window_id,
+                                             int32 x_offset,
+                                             int32 y_offset,
+                                             mojo.Insets hit_area);
 };
 
 interface WindowTreeHostClient {
diff --git a/components/mus/ws/display_manager.cc b/components/mus/ws/display_manager.cc
index 03eb620d..afbe6e9 100644
--- a/components/mus/ws/display_manager.cc
+++ b/components/mus/ws/display_manager.cc
@@ -98,21 +98,21 @@
   if (!draw_default_surface && !underlay_surface)
     return;
 
-  const gfx::Rect bounds_at_origin(window->bounds().size());
-
-  gfx::Transform quad_to_target_transform;
-  quad_to_target_transform.Translate(absolute_bounds.x(), absolute_bounds.y());
-
-  cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
-  // TODO(fsamuel): These clipping and visible rects are incorrect. They need
-  // to be populated from CompositorFrame structs.
-  sqs->SetAll(
-      quad_to_target_transform, bounds_at_origin.size() /* layer_bounds */,
-      bounds_at_origin /* visible_layer_bounds */,
-      bounds_at_origin /* clip_rect */, false /* is_clipped */,
-      window->opacity(), SkXfermode::kSrc_Mode, 0 /* sorting-context_id */);
-
   if (draw_default_surface) {
+    gfx::Transform quad_to_target_transform;
+    quad_to_target_transform.Translate(absolute_bounds.x(),
+                                       absolute_bounds.y());
+
+    cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
+
+    const gfx::Rect bounds_at_origin(window->bounds().size());
+    // TODO(fsamuel): These clipping and visible rects are incorrect. They need
+    // to be populated from CompositorFrame structs.
+    sqs->SetAll(
+        quad_to_target_transform, bounds_at_origin.size() /* layer_bounds */,
+        bounds_at_origin /* visible_layer_bounds */,
+        bounds_at_origin /* clip_rect */, false /* is_clipped */,
+        window->opacity(), SkXfermode::kSrc_Mode, 0 /* sorting-context_id */);
     auto quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
     quad->SetAll(sqs, bounds_at_origin /* rect */,
                  gfx::Rect() /* opaque_rect */,
@@ -120,6 +120,20 @@
                  default_surface->id());
   }
   if (underlay_surface) {
+    const gfx::Rect underlay_absolute_bounds =
+        absolute_bounds - window->underlay_offset();
+    gfx::Transform quad_to_target_transform;
+    quad_to_target_transform.Translate(underlay_absolute_bounds.x(),
+                                       underlay_absolute_bounds.y());
+    cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
+    const gfx::Rect bounds_at_origin(
+        underlay_surface->last_submitted_frame_size());
+    sqs->SetAll(
+        quad_to_target_transform, bounds_at_origin.size() /* layer_bounds */,
+        bounds_at_origin /* visible_layer_bounds */,
+        bounds_at_origin /* clip_rect */, false /* is_clipped */,
+        window->opacity(), SkXfermode::kSrc_Mode, 0 /* sorting-context_id */);
+
     auto quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
     quad->SetAll(sqs, bounds_at_origin /* rect */,
                  gfx::Rect() /* opaque_rect */,
diff --git a/components/mus/ws/server_window.cc b/components/mus/ws/server_window.cc
index 43fecc60..29b8ec1 100644
--- a/components/mus/ws/server_window.cc
+++ b/components/mus/ws/server_window.cc
@@ -331,6 +331,14 @@
   return surface_manager_.get();
 }
 
+void ServerWindow::SetUnderlayOffset(const gfx::Vector2d& offset) {
+  if (offset == underlay_offset_)
+    return;
+
+  underlay_offset_ = offset;
+  delegate_->OnScheduleWindowPaint(this);
+}
+
 #if !defined(NDEBUG)
 std::string ServerWindow::GetDebugWindowHierarchy() const {
   std::string result;
diff --git a/components/mus/ws/server_window.h b/components/mus/ws/server_window.h
index 9289125..89d291b3 100644
--- a/components/mus/ws/server_window.h
+++ b/components/mus/ws/server_window.h
@@ -17,6 +17,7 @@
 #include "mojo/public/cpp/bindings/binding.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/vector2d.h"
 #include "ui/gfx/transform.h"
 #include "ui/platform_window/text_input_state.h"
 
@@ -138,6 +139,10 @@
     return surface_manager_.get();
   }
 
+  // Offset of the underlay from the the window bounds (used for shadows).
+  const gfx::Vector2d& underlay_offset() const { return underlay_offset_; }
+  void SetUnderlayOffset(const gfx::Vector2d& offset);
+
   ServerWindowDelegate* delegate() { return delegate_; }
 
 #if !defined(NDEBUG)
@@ -183,6 +188,8 @@
 
   Properties properties_;
 
+  gfx::Vector2d underlay_offset_;
+
   base::ObserverList<ServerWindowObserver> observers_;
 
   DISALLOW_COPY_AND_ASSIGN(ServerWindow);
diff --git a/components/mus/ws/server_window_surface.h b/components/mus/ws/server_window_surface.h
index 99e0e52..378c09d 100644
--- a/components/mus/ws/server_window_surface.h
+++ b/components/mus/ws/server_window_surface.h
@@ -39,6 +39,10 @@
 
   ~ServerWindowSurface() override;
 
+  const gfx::Size& last_submitted_frame_size() const {
+    return last_submitted_frame_size_;
+  }
+
   // mojom::Surface:
   void SubmitCompositorFrame(
       mojom::CompositorFramePtr frame,
diff --git a/components/mus/ws/window_tree_host_impl.cc b/components/mus/ws/window_tree_host_impl.cc
index bba8925b..87d2a4ff 100644
--- a/components/mus/ws/window_tree_host_impl.cc
+++ b/components/mus/ws/window_tree_host_impl.cc
@@ -153,6 +153,21 @@
   focus_controller_->ActivateNextWindow();
 }
 
+void WindowTreeHostImpl::SetUnderlaySurfaceOffsetAndExtendedHitArea(
+    Id window_id,
+    int32_t x_offset,
+    int32_t y_offset,
+    mojo::InsetsPtr hit_area) {
+  ServerWindow* window =
+      connection_manager_->GetWindow(WindowIdFromTransportId(window_id));
+  if (!window)
+    return;
+
+  window->SetUnderlayOffset(gfx::Vector2d(x_offset, y_offset));
+
+  // TODO(sky): support hit area.
+}
+
 void WindowTreeHostImpl::OnClientClosed() {
   // |display_manager_.reset()| destroys the display-manager first, and then
   // sets |display_manager_| to nullptr. However, destroying |display_manager_|
diff --git a/components/mus/ws/window_tree_host_impl.h b/components/mus/ws/window_tree_host_impl.h
index 35a05c8..3850a3c 100644
--- a/components/mus/ws/window_tree_host_impl.h
+++ b/components/mus/ws/window_tree_host_impl.h
@@ -99,6 +99,11 @@
   void AddActivationParent(uint32_t window_id) override;
   void RemoveActivationParent(uint32_t window_id) override;
   void ActivateNextWindow() override;
+  void SetUnderlaySurfaceOffsetAndExtendedHitArea(
+      Id window_id,
+      int32_t x_offset,
+      int32_t y_offset,
+      mojo::InsetsPtr hit_area) override;
 
  private:
   void OnClientClosed();
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index b1fde40b..7133cdd 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -424,6 +424,8 @@
   if (use_aura) {
     deps += [
       "//components/bitmap_uploader",
+      "//components/mus/public/cpp",
+      "//components/mus/public/interfaces",
       "//ui/aura",
       "//ui/aura_extra",
       "//ui/strings",
diff --git a/content/browser/DEPS b/content/browser/DEPS
index 298ec09..dec16bf 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -3,6 +3,7 @@
   # depend on components which we share with the mojo html_viewer.
   "+components/mime_util",
   "+components/mus/public/interfaces",
+  "+components/mus/public",
   "+components/scheduler/common",
   "+components/tracing",
   "+components/url_formatter",
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 8f93e67..ad3d8ad4 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -933,6 +933,7 @@
 #if defined(MOJO_SHELL_CLIENT)
   if (IsRunningInMojoShell()) {
     MojoShellConnectionImpl::Create();
+    MojoShellConnectionImpl::Get()->BindToCommandLinePlatformChannel();
 #if defined(USE_AURA)
     views::WindowManagerConnection::Create(
         MojoShellConnection::Get()->GetApplication());
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 7562c0f..7e0a7669 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -73,10 +73,9 @@
     // plan on how to display the UI for that.
     DCHECK(params->prefer_cache());
     DCHECK_EQ("POST", params->method());
-    ScopedVector<net::UploadElementReader> element_readers;
-    request->set_upload(make_scoped_ptr(
-        new net::ElementsUploadDataStream(element_readers.Pass(),
-                                          params->post_id())));
+    std::vector<scoped_ptr<net::UploadElementReader>> element_readers;
+    request->set_upload(make_scoped_ptr(new net::ElementsUploadDataStream(
+        std::move(element_readers), params->post_id())));
   }
 
   // If we're not at the beginning of the file, retrieve only the remaining
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc
index 78fb9cf..8904071 100644
--- a/content/browser/frame_host/navigation_handle_impl.cc
+++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -288,7 +288,7 @@
 void NavigationHandleImpl::ReadyToCommitNavigation(
     RenderFrameHostImpl* render_frame_host,
     scoped_refptr<net::HttpResponseHeaders> response_headers) {
-  DCHECK(!render_frame_host_);
+  DCHECK(!render_frame_host_ || render_frame_host_ == render_frame_host);
   render_frame_host_ = render_frame_host;
   response_headers_ = response_headers;
   state_ = READY_TO_COMMIT;
@@ -304,7 +304,7 @@
 void NavigationHandleImpl::DidCommitNavigation(
     bool same_page,
     RenderFrameHostImpl* render_frame_host) {
-  CHECK(!render_frame_host_ || render_frame_host_ == render_frame_host);
+  DCHECK(!render_frame_host_ || render_frame_host_ == render_frame_host);
   is_same_page_ = same_page;
   render_frame_host_ = render_frame_host;
   state_ = net_error_code_ == net::OK ? DID_COMMIT : DID_COMMIT_ERROR_PAGE;
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index ce8891c9..3e3a497 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -151,8 +151,6 @@
       // DidStartProvisionalLoad should not correspond to a new navigation.
       DCHECK_EQ(url, render_frame_host->navigation_handle()->GetURL());
       render_frame_host->navigation_handle()->set_is_transferring(false);
-      render_frame_host->navigation_handle()->set_render_frame_host(
-          render_frame_host);
       return;
     }
 
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 053f5bc..70c8818 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1041,6 +1041,8 @@
 void RenderFrameHostImpl::SetNavigationHandle(
     scoped_ptr<NavigationHandleImpl> navigation_handle) {
   navigation_handle_ = navigation_handle.Pass();
+  if (navigation_handle_)
+    navigation_handle_->set_render_frame_host(this);
 }
 
 scoped_ptr<NavigationHandleImpl>
diff --git a/content/browser/loader/upload_data_stream_builder.cc b/content/browser/loader/upload_data_stream_builder.cc
index a79299c..7f6b517 100644
--- a/content/browser/loader/upload_data_stream_builder.cc
+++ b/content/browser/loader/upload_data_stream_builder.cc
@@ -77,27 +77,25 @@
     storage::BlobStorageContext* blob_context,
     storage::FileSystemContext* file_system_context,
     base::SingleThreadTaskRunner* file_task_runner) {
-  ScopedVector<net::UploadElementReader> element_readers;
+  std::vector<scoped_ptr<net::UploadElementReader>> element_readers;
   for (const auto& element : *body->elements()) {
     switch (element.type()) {
       case ResourceRequestBody::Element::TYPE_BYTES:
-        element_readers.push_back(new BytesElementReader(body, element));
+        element_readers.push_back(
+            make_scoped_ptr(new BytesElementReader(body, element)));
         break;
       case ResourceRequestBody::Element::TYPE_FILE:
-        element_readers.push_back(
-            new FileElementReader(body, file_task_runner, element));
+        element_readers.push_back(make_scoped_ptr(
+            new FileElementReader(body, file_task_runner, element)));
         break;
       case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM:
         // If |body| contains any filesystem URLs, the caller should have
         // supplied a FileSystemContext.
         DCHECK(file_system_context);
         element_readers.push_back(
-            new content::UploadFileSystemFileElementReader(
-                file_system_context,
-                element.filesystem_url(),
-                element.offset(),
-                element.length(),
-                element.expected_modification_time()));
+            make_scoped_ptr(new content::UploadFileSystemFileElementReader(
+                file_system_context, element.filesystem_url(), element.offset(),
+                element.length(), element.expected_modification_time())));
         break;
       case ResourceRequestBody::Element::TYPE_BLOB: {
         DCHECK_EQ(std::numeric_limits<uint64_t>::max(), element.length());
@@ -105,9 +103,10 @@
         scoped_ptr<storage::BlobDataHandle> handle =
             blob_context->GetBlobDataFromUUID(element.blob_uuid());
         storage::BlobDataHandle* handle_ptr = handle.get();
-        element_readers.push_back(new storage::UploadBlobElementReader(
-            handle_ptr->CreateReader(file_system_context, file_task_runner),
-            handle.Pass()));
+        element_readers.push_back(
+            make_scoped_ptr(new storage::UploadBlobElementReader(
+                handle_ptr->CreateReader(file_system_context, file_task_runner),
+                std::move(handle))));
         break;
       }
       case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
@@ -118,9 +117,8 @@
     }
   }
 
-  return make_scoped_ptr(
-      new net::ElementsUploadDataStream(element_readers.Pass(),
-                                        body->identifier()));
+  return make_scoped_ptr(new net::ElementsUploadDataStream(
+      std::move(element_readers), body->identifier()));
 }
 
 }  // namespace content
diff --git a/content/browser/loader/upload_data_stream_builder_unittest.cc b/content/browser/loader/upload_data_stream_builder_unittest.cc
index e323a4e9..c8f6b77 100644
--- a/content/browser/loader/upload_data_stream_builder_unittest.cc
+++ b/content/browser/loader/upload_data_stream_builder_unittest.cc
@@ -81,7 +81,7 @@
 
     const storage::UploadBlobElementReader* r3 =
         static_cast<storage::UploadBlobElementReader*>(
-            (*upload->GetElementReaders())[2]);
+            (*upload->GetElementReaders())[2].get());
     ASSERT_TRUE(r3);
     EXPECT_EQ("blobuuid", r3->uuid());
   }
diff --git a/content/browser/mojo/mojo_shell_client_host.cc b/content/browser/mojo/mojo_shell_client_host.cc
index 3a1acdf..8616a37 100644
--- a/content/browser/mojo/mojo_shell_client_host.cc
+++ b/content/browser/mojo/mojo_shell_client_host.cc
@@ -21,6 +21,7 @@
 namespace {
 
 const char kMojoShellInstanceURL[] = "mojo_shell_instance_url";
+const char kMojoPlatformFile[] = "mojo_platform_file";
 
 void DidCreateChannel(mojo::embedder::ChannelInfo* info) {}
 
@@ -46,16 +47,35 @@
   DISALLOW_COPY_AND_ASSIGN(InstanceURL);
 };
 
+class InstanceShellHandle : public base::SupportsUserData::Data {
+ public:
+  InstanceShellHandle(base::PlatformFile shell_handle)
+      : shell_handle_(shell_handle) {}
+  ~InstanceShellHandle() override {}
+
+  base::PlatformFile get() const { return shell_handle_; }
+
+ private:
+  base::PlatformFile shell_handle_;
+
+  DISALLOW_COPY_AND_ASSIGN(InstanceShellHandle);
+};
+
 void SetMojoApplicationInstanceURL(RenderProcessHost* render_process_host,
                                    const std::string& instance_url) {
   render_process_host->SetUserData(kMojoShellInstanceURL,
                                    new InstanceURL(instance_url));
 }
 
+void SetMojoPlatformFile(RenderProcessHost* render_process_host,
+                         base::PlatformFile platform_file) {
+  render_process_host->SetUserData(kMojoPlatformFile,
+                                   new InstanceShellHandle(platform_file));
+}
+
 }  // namespace
 
 void RegisterChildWithExternalShell(int child_process_id,
-                                    base::ProcessHandle process_handle,
                                     RenderProcessHost* render_process_host) {
   // Some process types get created before the main message loop.
   if (!MojoShellConnection::Get())
@@ -96,8 +116,7 @@
   // Send the other end to the child via Chrome IPC.
   base::PlatformFile client_file = PlatformFileFromScopedPlatformHandle(
       platform_channel_pair.PassClientHandle());
-  render_process_host->Send(new MojoMsg_BindExternalMojoShellHandle(
-      IPC::GetFileHandleForProcess(client_file, process_handle, true)));
+  SetMojoPlatformFile(render_process_host, client_file);
 
   // Store the URL on the RPH so client code can access it later via
   // GetMojoApplicationInstanceURL().
@@ -111,4 +130,15 @@
   return instance_url ? instance_url->get() : std::string();
 }
 
+void SendExternalMojoShellHandleToChild(
+    base::ProcessHandle process_handle,
+    RenderProcessHost* render_process_host) {
+  InstanceShellHandle* client_file = static_cast<InstanceShellHandle*>(
+      render_process_host->GetUserData(kMojoPlatformFile));
+  if (!client_file)
+    return;
+  render_process_host->Send(new MojoMsg_BindExternalMojoShellHandle(
+      IPC::GetFileHandleForProcess(client_file->get(), process_handle, true)));
+}
+
 }  // namespace content
diff --git a/content/browser/mojo/mojo_shell_client_host.h b/content/browser/mojo/mojo_shell_client_host.h
index 6f61f71e..c59924f 100644
--- a/content/browser/mojo/mojo_shell_client_host.h
+++ b/content/browser/mojo/mojo_shell_client_host.h
@@ -15,11 +15,9 @@
 
 // Creates a communication channel between the external Mojo shell and the
 // child. The server handle of this channel is shared with the external shell
-// via Mojo IPC and the client handle is shared with the child via Chrome IPC.
-// |child_process_id| is used to uniquify the child in the external shell's
-// instance map.
+// via Mojo IPC. |child_process_id| is used to uniquify the child in the
+// external shell's instance map.
 void RegisterChildWithExternalShell(int child_process_id,
-                                    base::ProcessHandle process_handle,
                                     RenderProcessHost* render_process_host);
 
 // Returns the URL associated with an instance corresponding to the renderer
@@ -28,6 +26,10 @@
 std::string GetMojoApplicationInstanceURL(
     RenderProcessHost* render_process_host);
 
+// Shares a client handle to the Mojo Shell with the child via Chrome IPC.
+void SendExternalMojoShellHandleToChild(base::ProcessHandle process_handle,
+                                        RenderProcessHost* render_process_host);
+
 }  // namespace content
 
 #endif  // CONTENT_BROWSER_MOJO_MOJO_SHELL_CLIENT_HOST_H_
diff --git a/content/browser/renderer_host/DEPS b/content/browser/renderer_host/DEPS
index 202bcdd..e20b5581 100644
--- a/content/browser/renderer_host/DEPS
+++ b/content/browser/renderer_host/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+cc/switches.h", # For cc command line switches.
+  "+components/mus/public",
   "+media/base",  # For media command line switches.
   "+media/audio/audio_util.h",  # For audio hardware sample-rate.
   "+third_party/zlib",
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 87964b50..edf1f43 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -575,6 +575,10 @@
   IPC::AttachmentBrokerPrivileged::CreateBrokerIfNeeded();
 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
 #endif  // USE_ATTACHMENT_BROKER
+
+#if defined(MOJO_SHELL_CLIENT)
+  RegisterChildWithExternalShell(id_, this);
+#endif
 }
 
 // static
@@ -2439,9 +2443,8 @@
                                          NotificationService::NoDetails());
 
 #if defined(MOJO_SHELL_CLIENT)
-  // Send a handle that the external Mojo shell can use to pass an Application
-  // request to the child.
-  RegisterChildWithExternalShell(id_, GetHandle(), this);
+  // Send the mojo shell handle to the renderer.
+  SendExternalMojoShellHandleToChild(GetHandle(), this);
 #endif
 
 #if defined(OS_WIN)
diff --git a/content/browser/renderer_host/render_widget_host_view_mus.cc b/content/browser/renderer_host/render_widget_host_view_mus.cc
index e371035..08e0058c3 100644
--- a/content/browser/renderer_host/render_widget_host_view_mus.cc
+++ b/content/browser/renderer_host/render_widget_host_view_mus.cc
@@ -4,7 +4,14 @@
 
 #include "content/browser/renderer_host/render_widget_host_view_mus.h"
 
+#include "components/mus/public/cpp/window.h"
+#include "components/mus/public/cpp/window_tree_connection.h"
+#include "content/browser/mojo/mojo_shell_client_host.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/common/render_widget_window_tree_client_factory.mojom.h"
+#include "content/public/common/mojo_shell_connection.h"
+#include "mojo/application/public/cpp/application_impl.h"
 
 namespace blink {
 struct WebScreenInfo;
@@ -13,10 +20,28 @@
 namespace content {
 
 RenderWidgetHostViewMus::RenderWidgetHostViewMus(
+    mus::Window* parent_window,
     RenderWidgetHostImpl* host,
     base::WeakPtr<RenderWidgetHostViewBase> platform_view)
     : host_(host), platform_view_(platform_view) {
+  DCHECK(parent_window);
+  mus::Window* window = parent_window->connection()->NewWindow();
+  window->SetVisible(true);
+  window->SetBounds(gfx::Rect(300, 300));
+  parent_window->AddChild(window);
+  window_.reset(new mus::ScopedWindowPtr(window));
   host_->SetView(this);
+
+  // Connect to the renderer, pass it a WindowTreeClient interface request
+  // and embed that client inside our mus window.
+  std::string url = GetMojoApplicationInstanceURL(host_->GetProcess());
+  mojom::RenderWidgetWindowTreeClientFactoryPtr factory;
+  MojoShellConnection::Get()->GetApplication()->ConnectToService(url, &factory);
+
+  mus::mojom::WindowTreeClientPtr window_tree_client;
+  factory->CreateWindowTreeClientForRenderWidget(
+      host_->GetRoutingID(), mojo::GetProxy(&window_tree_client));
+  window_->window()->Embed(window_tree_client.Pass());
 }
 
 RenderWidgetHostViewMus::~RenderWidgetHostViewMus() {}
@@ -37,6 +62,7 @@
 
 void RenderWidgetHostViewMus::SetSize(const gfx::Size& size) {
   size_ = size;
+  window_->window()->SetBounds(gfx::Rect(size));
   host_->WasResized();
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_mus.h b/content/browser/renderer_host/render_widget_host_view_mus.h
index 9974e41..d3ae71dc 100644
--- a/content/browser/renderer_host/render_widget_host_view_mus.h
+++ b/content/browser/renderer_host/render_widget_host_view_mus.h
@@ -6,7 +6,10 @@
 #define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_MUS_H_
 
 #include "base/macros.h"
+#include "components/mus/public/cpp/scoped_window_ptr.h"
+#include "components/mus/public/cpp/window.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
+#include "content/public/browser/render_process_host_observer.h"
 
 namespace content {
 
@@ -26,6 +29,7 @@
 class CONTENT_EXPORT RenderWidgetHostViewMus : public RenderWidgetHostViewBase {
  public:
   RenderWidgetHostViewMus(
+      mus::Window* parent_window,
       RenderWidgetHostImpl* widget,
       base::WeakPtr<RenderWidgetHostViewBase> platform_view);
   ~RenderWidgetHostViewMus() override;
@@ -119,6 +123,7 @@
 #endif
 
   RenderWidgetHostImpl* host_;
+  scoped_ptr<mus::ScopedWindowPtr> window_;
   gfx::Size size_;
   // The platform view for this RenderWidgetHostView.
   // RenderWidgetHostViewMus mostly only cares about stuff related to
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index c36e3a7..358754a 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -136,6 +136,7 @@
 #if defined(MOJO_SHELL_CLIENT)
 #include "content/browser/web_contents/web_contents_view_mus.h"
 #include "content/public/common/mojo_shell_connection.h"
+#include "ui/aura/mus/mus_util.h"
 #endif
 
 namespace content {
@@ -1391,8 +1392,11 @@
   if (MojoShellConnection::Get() &&
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kUseMusInRenderer)) {
-    view_.reset(new WebContentsViewMus(this, view_.Pass(),
-                                       &render_view_host_delegate_view_));
+    mus::Window* window = aura::GetMusWindow(params.context);
+    if (window) {
+      view_.reset(new WebContentsViewMus(this, window, view_.Pass(),
+                                         &render_view_host_delegate_view_));
+    }
   }
 #endif
 
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 8d55780..e78f4363 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -43,13 +43,11 @@
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/geometry/size.h"
 
-struct BrowserPluginHostMsg_ResizeGuest_Params;
 struct ViewHostMsg_DateTimeDialogValue_Params;
 
 namespace content {
 class BrowserPluginEmbedder;
 class BrowserPluginGuest;
-class BrowserPluginGuestManager;
 class DateTimeChooserAndroid;
 class DownloadItem;
 class GeolocationServiceContext;
diff --git a/content/browser/web_contents/web_contents_view_mus.cc b/content/browser/web_contents/web_contents_view_mus.cc
index 97e45f8..86de954 100644
--- a/content/browser/web_contents/web_contents_view_mus.cc
+++ b/content/browser/web_contents/web_contents_view_mus.cc
@@ -5,6 +5,8 @@
 #include "content/browser/web_contents/web_contents_view_mus.h"
 
 #include "build/build_config.h"
+#include "components/mus/public/cpp/window.h"
+#include "components/mus/public/cpp/window_tree_connection.h"
 #include "content/browser/renderer_host/render_widget_host_view_mus.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/render_widget_host_view.h"
@@ -17,12 +19,19 @@
 
 WebContentsViewMus::WebContentsViewMus(
     WebContentsImpl* web_contents,
+    mus::Window* parent_window,
     scoped_ptr<WebContentsView> platform_view,
     RenderViewHostDelegateView** delegate_view)
     : web_contents_(web_contents),
       platform_view_(platform_view.Pass()),
       platform_view_delegate_view_(*delegate_view) {
+  DCHECK(parent_window);
   *delegate_view = this;
+  mus::Window* window = parent_window->connection()->NewWindow();
+  window->SetVisible(true);
+  window->SetBounds(gfx::Rect(300, 300));
+  parent_window->AddChild(window);
+  window_.reset(new mus::ScopedWindowPtr(window));
 }
 
 WebContentsViewMus::~WebContentsViewMus() {}
@@ -52,6 +61,7 @@
   RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
   if (rwhv)
     rwhv->SetSize(size);
+  window_->window()->SetBounds(gfx::Rect(size));
 }
 
 void WebContentsViewMus::SetInitialFocus() {
@@ -85,7 +95,7 @@
       platform_view_->CreateViewForWidget(render_widget_host, true);
 
   return new RenderWidgetHostViewMus(
-      RenderWidgetHostImpl::From(render_widget_host),
+      window_->window(), RenderWidgetHostImpl::From(render_widget_host),
       platform_widget->GetWeakPtr());
 }
 
diff --git a/content/browser/web_contents/web_contents_view_mus.h b/content/browser/web_contents/web_contents_view_mus.h
index 173e6dd..5e4e4ed 100644
--- a/content/browser/web_contents/web_contents_view_mus.h
+++ b/content/browser/web_contents/web_contents_view_mus.h
@@ -9,6 +9,8 @@
 
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
+#include "components/mus/public/cpp/scoped_window_ptr.h"
+#include "components/mus/public/cpp/window.h"
 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
 #include "content/browser/web_contents/web_contents_view.h"
 #include "content/common/content_export.h"
@@ -28,6 +30,7 @@
   // WebContentsViewMus always has a backing platform dependent view,
   // |platform_view|.
   WebContentsViewMus(WebContentsImpl* web_contents,
+                     mus::Window* parent_window,
                      scoped_ptr<WebContentsView> platform_view,
                      RenderViewHostDelegateView** platform_view_delegate_view);
   ~WebContentsViewMus() override;
@@ -80,6 +83,8 @@
   // The WebContentsImpl whose contents we display.
   WebContentsImpl* web_contents_;
 
+  scoped_ptr<mus::ScopedWindowPtr> window_;
+
   // The platform dependent view backing this WebContentsView.
   // Calls to this WebContentsViewMus are forwarded to |platform_view_|.
   scoped_ptr<WebContentsView> platform_view_;
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index cfae659..176a525d 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -728,7 +728,7 @@
   mojo::ScopedMessagePipeHandle message_pipe =
       mojo_shell_channel_init_.Init(handle, GetIOTaskRunner());
   DCHECK(message_pipe.is_valid());
-  MojoShellConnectionImpl::CreateWithMessagePipe(message_pipe.Pass());
+  MojoShellConnectionImpl::Get()->BindToMessagePipe(message_pipe.Pass());
 #endif  // defined(MOJO_SHELL_CLIENT)
 }
 
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 339032d..faf6e0d 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -534,6 +534,7 @@
     "permission_service.mojom",
     "presentation/presentation_service.mojom",
     "process_control.mojom",
+    "render_widget_window_tree_client_factory.mojom",
     "routed_service_provider.mojom",
     "service_port_service.mojom",
     "service_worker/embedded_worker_setup.mojom",
diff --git a/content/common/mojo/mojo_shell_connection_impl.cc b/content/common/mojo/mojo_shell_connection_impl.cc
index 25c8be1c..3c0714d 100644
--- a/content/common/mojo/mojo_shell_connection_impl.cc
+++ b/content/common/mojo/mojo_shell_connection_impl.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
+#include "base/stl_util.h"
 #include "base/threading/thread_local.h"
 #include "mojo/application/public/cpp/application_delegate.h"
 #include "mojo/application/public/cpp/application_impl.h"
@@ -30,21 +31,34 @@
 
 // static
 void MojoShellConnectionImpl::Create() {
-  DCHECK(IsRunningInMojoShell());
-  CreateWithMessagePipe(mojo::ScopedMessagePipeHandle());
-}
-
-// static
-void MojoShellConnectionImpl::CreateWithMessagePipe(
-    mojo::ScopedMessagePipeHandle handle) {
   DCHECK(!lazy_tls_ptr.Pointer()->Get());
   MojoShellConnectionImpl* connection = new MojoShellConnectionImpl;
   lazy_tls_ptr.Pointer()->Set(connection);
-  connection->WaitForShell(handle.Pass());
+}
+
+// static
+MojoShellConnectionImpl* MojoShellConnectionImpl::Get() {
+  return static_cast<MojoShellConnectionImpl*>(MojoShellConnection::Get());
+}
+
+void MojoShellConnectionImpl::BindToCommandLinePlatformChannel() {
+  DCHECK(IsRunningInMojoShell());
+  if (initialized_)
+    return;
+  WaitForShell(mojo::ScopedMessagePipeHandle());
+}
+
+void MojoShellConnectionImpl::BindToMessagePipe(
+    mojo::ScopedMessagePipeHandle handle) {
+  if (initialized_)
+    return;
+  WaitForShell(handle.Pass());
 }
 
 MojoShellConnectionImpl::MojoShellConnectionImpl() : initialized_(false) {}
-MojoShellConnectionImpl::~MojoShellConnectionImpl() {}
+MojoShellConnectionImpl::~MojoShellConnectionImpl() {
+  STLDeleteElements(&listeners_);
+}
 
 void MojoShellConnectionImpl::WaitForShell(
     mojo::ScopedMessagePipeHandle handle) {
diff --git a/content/common/mojo/mojo_shell_connection_impl.h b/content/common/mojo/mojo_shell_connection_impl.h
index 8891acb..872ee2b 100644
--- a/content/common/mojo/mojo_shell_connection_impl.h
+++ b/content/common/mojo/mojo_shell_connection_impl.h
@@ -28,13 +28,22 @@
                                 public mojo::ApplicationDelegate {
  public:
   // Creates an instance of this class and stuffs it in TLS on the calling
-  // thread. Retrieve it using MojoShellConnection::Get(). Blocks the calling
-  // thread until calling GetApplication() will return an Initialized()
-  // application with a bound ShellPtr.
+  // thread. Retrieve it using MojoShellConnection::Get().
   static void Create();
-  // Same as Create(), but receives a handle instead of looking for one on the
-  // command line.
-  static void CreateWithMessagePipe(mojo::ScopedMessagePipeHandle handle);
+
+  // Will return null if no connection has been established (either because it
+  // hasn't happened yet or the application was not spawned from the external
+  // Mojo shell).
+  static MojoShellConnectionImpl* Get();
+
+  // Blocks the calling thread until calling GetApplication() will return an
+  // Initialized() application with a bound ShellPtr. This call is a no-op
+  // if the connection has already been initialized.
+  void BindToCommandLinePlatformChannel();
+
+  // Same as BindToCommandLinePlatformChannel(), but receives a |handle| instead
+  // of looking for one on the command line.
+  void BindToMessagePipe(mojo::ScopedMessagePipeHandle handle);
 
  private:
   MojoShellConnectionImpl();
diff --git a/content/common/render_widget_window_tree_client_factory.mojom b/content/common/render_widget_window_tree_client_factory.mojom
new file mode 100644
index 0000000..e6d88d7
--- /dev/null
+++ b/content/common/render_widget_window_tree_client_factory.mojom
@@ -0,0 +1,13 @@
+// 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.
+
+module content.mojom;
+
+import "components/mus/public/interfaces/window_tree.mojom";
+
+interface RenderWidgetWindowTreeClientFactory {
+  CreateWindowTreeClientForRenderWidget(
+      uint32 routing_id,
+      mus.mojom.WindowTreeClient& window_tree_client);
+};
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
index 159aa7b4..15159a26 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
@@ -119,8 +119,8 @@
     /**
      * Default factory for AdapterInputConnection classes.
      */
-    public static class AdapterInputConnectionFactory {
-        public AdapterInputConnection get(View view, ImeAdapter imeAdapter, int initialSelStart,
+    static class AdapterInputConnectionFactory {
+        AdapterInputConnection get(View view, ImeAdapter imeAdapter, int initialSelStart,
                 int initialSelEnd, EditorInfo outAttrs) {
             return new AdapterInputConnection(
                     view, imeAdapter, initialSelStart, initialSelEnd, outAttrs);
@@ -162,15 +162,6 @@
         mInputMethodManagerWrapper = immw;
     }
 
-    /**
-     * Should be only used by AdapterInputConnection.
-     * @return InputMethodManagerWrapper that should receive all the calls directed to
-     *         InputMethodManager.
-     */
-    InputMethodManagerWrapper getInputMethodManagerWrapper() {
-        return mInputMethodManagerWrapper;
-    }
-
     @VisibleForTesting
     void setInputConnectionFactory(AdapterInputConnectionFactory factory) {
         mInputConnectionFactory = factory;
@@ -370,7 +361,7 @@
     }
 
     @VisibleForTesting
-    public void setInputTypeForTest(int textInputType) {
+    void setInputTypeForTest(int textInputType) {
         mTextInputType = textInputType;
     }
 
@@ -469,7 +460,7 @@
     }
 
     @VisibleForTesting
-    protected void finishComposingText() {
+    void finishComposingText() {
         if (mNativeImeAdapterAndroid == 0) return;
         nativeFinishComposingText(mNativeImeAdapterAndroid);
     }
@@ -575,7 +566,7 @@
     }
 
     @CalledByNative
-    void detach() {
+    private void detach() {
         Log.d(TAG, "detach");
         mNativeImeAdapterAndroid = 0;
     }
diff --git a/content/public/common/mojo_shell_connection.h b/content/public/common/mojo_shell_connection.h
index af4cce1..e42e3c0 100644
--- a/content/public/common/mojo_shell_connection.h
+++ b/content/public/common/mojo_shell_connection.h
@@ -29,7 +29,6 @@
     virtual bool ConfigureIncomingConnection(
         mojo::ApplicationConnection* connection) = 0;
 
-   protected:
     virtual ~Listener() {}
   };
 
@@ -47,6 +46,7 @@
 
   // [De]Register an impl of Listener that will be consulted when the wrapped
   // ApplicationImpl exposes services to inbound connections.
+  // Registered listeners are owned by this MojoShellConnection.
   virtual void AddListener(Listener* listener) = 0;
   virtual void RemoveListener(Listener* listener) = 0;
 
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 28e9fbd8e..7c75a47 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -19,6 +19,7 @@
   configs += [
     "//content:content_implementation",
     "//build/config/compiler:no_size_t_to_int_warning",
+    "//content/public/common:mojo_shell_client",
   ]
 
   deps = [
@@ -74,6 +75,15 @@
     "//v8",
   ]
 
+  if (use_aura) {
+    sources += [
+      "render_widget_mus_connection.cc",
+      "render_widget_mus_connection.h",
+      "render_widget_window_tree_client_factory.cc",
+      "render_widget_window_tree_client_factory.h",
+    ]
+  }
+
   if (is_mac) {
     sources -= [
       "webscrollbarbehavior_impl_gtkoraura.cc",
diff --git a/content/renderer/DEPS b/content/renderer/DEPS
index e5367fc..b070955 100644
--- a/content/renderer/DEPS
+++ b/content/renderer/DEPS
@@ -1,6 +1,7 @@
 include_rules = [
   # Allow inclusion of specific components that we depend on. We may only
   # depend on components which we share with the mojo html_viewer.
+  "+components/mus/public",
   "+components/scheduler",
   "+components/url_formatter",
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 1a9097e..982aedbe 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -662,12 +662,10 @@
         RenderFrameProxy::FromRoutingID(proxy_routing_id);
     CHECK(proxy);
     render_frame = RenderFrameImpl::Create(proxy->render_view(), routing_id);
-    web_frame =
-        blink::WebLocalFrame::create(replicated_state.scope, render_frame);
     render_frame->proxy_routing_id_ = proxy_routing_id;
-    web_frame->initializeToReplaceRemoteFrame(
-        proxy->web_frame(), WebString::fromUTF8(replicated_state.name),
-        replicated_state.sandbox_flags, frame_owner_properties);
+    web_frame = blink::WebLocalFrame::createProvisional(
+        render_frame, proxy->web_frame(), replicated_state.sandbox_flags,
+        frame_owner_properties);
   }
   render_frame->SetWebFrame(web_frame);
   CHECK(parent_routing_id != MSG_ROUTING_NONE || !web_frame->parent());
@@ -3223,9 +3221,7 @@
 
 void RenderFrameImpl::didUpdateCurrentHistoryItem(blink::WebLocalFrame* frame) {
   DCHECK(!frame_ || frame_ == frame);
-  // TODO(nasko): Move implementation here. Needed methods:
-  // * StartNavStateSyncTimerIfNecessary
-  render_view_->didUpdateCurrentHistoryItem(frame);
+  render_view_->StartNavStateSyncTimerIfNecessary(this);
 }
 
 void RenderFrameImpl::didChangeThemeColor() {
@@ -3700,9 +3696,7 @@
 
 void RenderFrameImpl::didChangeScrollOffset(blink::WebLocalFrame* frame) {
   DCHECK(!frame_ || frame_ == frame);
-  // TODO(nasko): Move implementation here. Needed methods:
-  // * StartNavStateSyncTimerIfNecessary
-  render_view_->didChangeScrollOffset(frame);
+  render_view_->StartNavStateSyncTimerIfNecessary(this);
 
   FOR_EACH_OBSERVER(RenderFrameObserver, observers_, DidChangeScrollOffset());
 }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 43f61d7..80cafda 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -617,6 +617,9 @@
   scoped_ptr<media::MediaPermission> CreateMediaPermissionProxy(
       scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner);
 
+  // Sends the current frame's navigation state to the browser.
+  void SendUpdateState();
+
  protected:
   explicit RenderFrameImpl(const CreateParams& params);
 
@@ -844,9 +847,6 @@
                    blink::WebFrame* frame,
                    blink::WebFrameLoadType load_type);
 
-  // Sends the current frame's navigation state to the browser.
-  void SendUpdateState();
-
   // Sends a proper FrameHostMsg_DidFailProvisionalLoadWithError_Params IPC for
   // the failed request |request|.
   void SendFailedProvisionalLoad(const blink::WebURLRequest& request,
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 3b17ea0d..bf5b570 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -199,6 +199,11 @@
 #include "v8/src/third_party/vtune/v8-vtune.h"
 #endif
 
+#if defined(MOJO_SHELL_CLIENT)
+#include "content/public/common/mojo_shell_connection.h"
+#include "content/renderer/render_widget_window_tree_client_factory.h"
+#endif
+
 using base::ThreadRestrictions;
 using blink::WebDocument;
 using blink::WebFrame;
@@ -768,6 +773,13 @@
 
   service_registry()->AddService<EmbeddedWorkerSetup>(
       base::Bind(CreateEmbeddedWorkerSetup));
+
+#if defined(MOJO_SHELL_CLIENT)
+  // We may not have a MojoShellConnection object in tests that directly
+  // instantiate a RenderThreadImpl.
+  if (MojoShellConnection::Get())
+    CreateRenderWidgetWindowTreeClientFactory();
+#endif
 }
 
 RenderThreadImpl::~RenderThreadImpl() {
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index 1a9a23d..bcdc6afd 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -453,11 +453,6 @@
 
 // Test that we get form state change notifications when input fields change.
 TEST_F(RenderViewImplTest, OnNavStateChanged) {
-  // TODO(creis): Make the UpdateState timer work in OOPIF modes.
-  // See https://crbug.com/545219.
-  if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-    return;
-
   // Don't want any delay for form state sync changes. This will still post a
   // message so updates will get coalesced, but as soon as we spin the message
   // loop, it will generate an update.
@@ -467,6 +462,8 @@
 
   // We should NOT have gotten a form state change notification yet.
   EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
+      FrameHostMsg_UpdateState::ID));
+  EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
       ViewHostMsg_UpdateState::ID));
   render_thread_->sink().ClearMessages();
 
@@ -475,8 +472,13 @@
   ExecuteJavaScriptForTests(
       "document.getElementById('elt_text').value = 'foo';");
   ProcessPendingMessages();
-  EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
-      ViewHostMsg_UpdateState::ID));
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+    EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
+        FrameHostMsg_UpdateState::ID));
+  } else {
+    EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
+        ViewHostMsg_UpdateState::ID));
+  }
 }
 
 TEST_F(RenderViewImplTest, OnNavigationHttpPost) {
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 019f894..a92388e 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -1484,6 +1484,20 @@
       routing_id_, page_id_, HistoryEntryToPageState(entry)));
 }
 
+void RenderViewImpl::SendFrameStateUpdates() {
+  // We only use this path in OOPIF-enabled modes.
+  DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
+
+  // Tell each frame with pending state to send its UpdateState message.
+  for (int render_frame_routing_id : frames_with_pending_state_) {
+    RenderFrameImpl* frame =
+        RenderFrameImpl::FromRoutingID(render_frame_routing_id);
+    if (frame)
+      frame->SendUpdateState();
+  }
+  frames_with_pending_state_.clear();
+}
+
 void RenderViewImpl::ApplyWebPreferencesInternal(
     const WebPreferences& prefs,
     blink::WebView* web_view,
@@ -1848,11 +1862,10 @@
   return window_rect;
 }
 
-void RenderViewImpl::StartNavStateSyncTimerIfNecessary() {
-  // TODO(creis): Move this to RenderFrameHost.  In the meantime, we'll ignore
-  // state changes between navigation events in OOPIF-enabled modes.
+void RenderViewImpl::StartNavStateSyncTimerIfNecessary(RenderFrameImpl* frame) {
+  // In OOPIF modes, keep track of which frames have pending updates.
   if (SiteIsolationPolicy::UseSubframeNavigationEntries())
-    return;
+    frames_with_pending_state_.insert(frame->GetRoutingID());
 
   int delay;
   if (send_content_state_immediately_)
@@ -1871,8 +1884,15 @@
     nav_state_sync_timer_.Stop();
   }
 
-  nav_state_sync_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(delay), this,
-                              &RenderViewImpl::SendUpdateState);
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+    // In OOPIF modes, tell each frame with pending state to inform the browser.
+    nav_state_sync_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(delay), this,
+                                &RenderViewImpl::SendFrameStateUpdates);
+  } else {
+    // By default, send an UpdateState for the current history item.
+    nav_state_sync_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(delay), this,
+                                &RenderViewImpl::SendUpdateState);
+  }
 }
 
 void RenderViewImpl::setMouseOverURL(const WebURL& url) {
@@ -2133,10 +2153,6 @@
   SendUpdateFaviconURL(urls);
 }
 
-void RenderViewImpl::didUpdateCurrentHistoryItem(WebLocalFrame* frame) {
-  StartNavStateSyncTimerIfNecessary();
-}
-
 void RenderViewImpl::CheckPreferredSize() {
   // We don't always want to send the change messages over IPC, only if we've
   // been put in that mode by getting a |ViewMsg_EnablePreferredSizeChangedMode|
@@ -2153,10 +2169,6 @@
                                                       preferred_size_));
 }
 
-void RenderViewImpl::didChangeScrollOffset(WebLocalFrame* frame) {
-  StartNavStateSyncTimerIfNecessary();
-}
-
 void RenderViewImpl::SendFindReply(int request_id,
                                    int match_count,
                                    int ordinal,
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 4739a1e..78923fd 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -291,6 +291,11 @@
   void TransferActiveWheelFlingAnimation(
       const blink::WebActiveWheelFlingParameters& params);
 
+  // Starts a timer to send an UpdateState message on behalf of |frame|, if the
+  // timer isn't already running. This allows multiple state changing events to
+  // be coalesced into one update.
+  void StartNavStateSyncTimerIfNecessary(RenderFrameImpl* frame);
+
   // Synchronously sends the current navigation state to the browser.
   void SendUpdateState();
 
@@ -574,8 +579,6 @@
   // are to be moved to RenderFrameImpl <http://crbug.com/361761>.
 
   void didChangeIcon(blink::WebLocalFrame*, blink::WebIconURL::Type);
-  void didUpdateCurrentHistoryItem(blink::WebLocalFrame* frame);
-  void didChangeScrollOffset(blink::WebLocalFrame* frame);
 
   static Referrer GetReferrerFromRequest(
       blink::WebFrame* frame,
@@ -714,15 +717,16 @@
                      const blink::WebRect& selection_rect,
                      bool final_status_update);
 
-  // Starts nav_state_sync_timer_ if it isn't already running.
-  void StartNavStateSyncTimerIfNecessary();
-
 #if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX))
   void UpdateFontRenderingFromRendererPrefs();
 #else
   void UpdateFontRenderingFromRendererPrefs() {}
 #endif
 
+  // In OOPIF-enabled modes, this tells each RenderFrame with a pending state
+  // update to inform the browser process.
+  void SendFrameStateUpdates();
+
   // Update the target url and tell the browser that the target URL has changed.
   // If |url| is empty, show |fallback_url|.
   void UpdateTargetURL(const GURL& url, const GURL& fallback_url);
@@ -825,6 +829,10 @@
   // StartNavStateSyncTimerIfNecessary).
   base::OneShotTimer nav_state_sync_timer_;
 
+  // Set of RenderFrame routing IDs for frames that having pending UpdateState
+  // messages to send when the next |nav_state_sync_timer_| fires.
+  std::set<int> frames_with_pending_state_;
+
   // Page IDs ------------------------------------------------------------------
   // See documentation in RenderView.
   int32 page_id_;
diff --git a/content/renderer/render_widget_mus_connection.cc b/content/renderer/render_widget_mus_connection.cc
new file mode 100644
index 0000000..297e0f22
--- /dev/null
+++ b/content/renderer/render_widget_mus_connection.cc
@@ -0,0 +1,88 @@
+// 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 "content/renderer/render_widget_mus_connection.h"
+
+#include "components/mus/public/interfaces/compositor_frame.mojom.h"
+#include "components/mus/public/interfaces/window_tree.mojom.h"
+#include "content/public/common/mojo_shell_connection.h"
+#include "mojo/application/public/cpp/application_impl.h"
+#include "mojo/converters/geometry/geometry_type_converters.h"
+#include "mojo/converters/surfaces/surfaces_utils.h"
+
+namespace content {
+
+RenderWidgetMusConnection::RenderWidgetMusConnection(
+    int routing_id,
+    mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request)
+    : routing_id_(routing_id), root_(nullptr) {
+  // TODO(fsamuel): We should probably introduce a
+  // RenderWidgetMusConnection::FromRoutingID that's usable from RenderWidget.
+  // TODO(fsamuel): We probably want to pause processing of incoming
+  // messages until we have an associated RenderWidget.
+  mus::WindowTreeConnection::Create(
+      this, request.Pass(),
+      mus::WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED);
+}
+
+RenderWidgetMusConnection::~RenderWidgetMusConnection() {}
+
+void RenderWidgetMusConnection::SubmitCompositorFrame() {
+  const gfx::Rect bounds(root_->bounds());
+  mus::mojom::PassPtr pass = mojo::CreateDefaultPass(1, bounds);
+  mus::mojom::CompositorFramePtr frame = mus::mojom::CompositorFrame::New();
+
+  mus::mojom::CompositorFrameMetadataPtr meta =
+      mus::mojom::CompositorFrameMetadata::New();
+  meta->device_scale_factor = 1.0f;
+  frame->metadata = meta.Pass();
+
+  frame->resources.resize(0u);
+
+  pass->quads.resize(0u);
+  pass->shared_quad_states.push_back(mojo::CreateDefaultSQS(bounds.size()));
+
+  mus::mojom::QuadPtr quad = mus::mojom::Quad::New();
+  quad->material = mus::mojom::MATERIAL_SOLID_COLOR;
+  quad->rect = mojo::Rect::From(bounds);
+  quad->opaque_rect = mojo::Rect::New();
+  quad->visible_rect = mojo::Rect::From(bounds);
+  quad->needs_blending = false;
+  quad->shared_quad_state_index = 0u;
+
+  mus::mojom::SolidColorQuadStatePtr color_state =
+      mus::mojom::SolidColorQuadState::New();
+  color_state->color = mus::mojom::Color::New();
+  color_state->color->rgba = 0xff00ff00;
+  color_state->force_anti_aliasing_off = false;
+
+  quad->solid_color_quad_state = color_state.Pass();
+  pass->quads.push_back(quad.Pass());
+  frame->passes.push_back(pass.Pass());
+  surface_->SubmitCompositorFrame(frame.Pass(), mojo::Closure());
+}
+
+void RenderWidgetMusConnection::OnConnectionLost(
+    mus::WindowTreeConnection* connection) {
+  delete this;
+}
+
+void RenderWidgetMusConnection::OnEmbed(mus::Window* root) {
+  root_ = root;
+  root_->AddObserver(this);
+  surface_ = root_->RequestSurface(mus::mojom::SURFACE_TYPE_DEFAULT);
+  surface_->BindToThread();
+  SubmitCompositorFrame();
+}
+
+void RenderWidgetMusConnection::OnUnembed() {}
+
+void RenderWidgetMusConnection::OnWindowBoundsChanged(
+    mus::Window* window,
+    const gfx::Rect& old_bounds,
+    const gfx::Rect& new_bounds) {
+  SubmitCompositorFrame();
+}
+
+}  // namespace content
diff --git a/content/renderer/render_widget_mus_connection.h b/content/renderer/render_widget_mus_connection.h
new file mode 100644
index 0000000..d82d67e
--- /dev/null
+++ b/content/renderer/render_widget_mus_connection.h
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_RENDER_WIDGET_MUS_CONNECTION_H_
+#define CONTENT_RENDERER_RENDER_WIDGET_MUS_CONNECTION_H_
+
+#include "base/macros.h"
+#include "components/mus/public/cpp/window.h"
+#include "components/mus/public/cpp/window_observer.h"
+#include "components/mus/public/cpp/window_surface.h"
+#include "components/mus/public/cpp/window_tree_connection.h"
+#include "components/mus/public/cpp/window_tree_delegate.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+namespace content {
+
+class RenderWidgetMusConnection : public mus::WindowTreeDelegate,
+                                  public mus::WindowObserver {
+ public:
+  RenderWidgetMusConnection(
+      int routing_id,
+      mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request);
+  ~RenderWidgetMusConnection() override;
+
+ private:
+  void SubmitCompositorFrame();
+
+  // WindowTreeDelegate implementation:
+  void OnConnectionLost(mus::WindowTreeConnection* connection) override;
+  void OnEmbed(mus::Window* root) override;
+  void OnUnembed() override;
+  void OnWindowBoundsChanged(mus::Window* window,
+                             const gfx::Rect& old_bounds,
+                             const gfx::Rect& new_bounds) override;
+
+  const int routing_id_;
+  mus::Window* root_;
+  scoped_ptr<mus::WindowSurface> surface_;
+
+  DISALLOW_COPY_AND_ASSIGN(RenderWidgetMusConnection);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_RENDERER_RENDER_WIDGET_MUS_CONNECTION_H_
diff --git a/content/renderer/render_widget_window_tree_client_factory.cc b/content/renderer/render_widget_window_tree_client_factory.cc
new file mode 100644
index 0000000..fefec083
--- /dev/null
+++ b/content/renderer/render_widget_window_tree_client_factory.cc
@@ -0,0 +1,69 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/render_widget_window_tree_client_factory.h"
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "components/mus/public/interfaces/window_tree.mojom.h"
+#include "content/common/render_widget_window_tree_client_factory.mojom.h"
+#include "content/public/common/mojo_shell_connection.h"
+#include "content/renderer/render_widget_mus_connection.h"
+#include "mojo/application/public/cpp/application_connection.h"
+#include "mojo/application/public/cpp/interface_factory.h"
+#include "mojo/common/weak_binding_set.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+// This object's lifetime is managed by MojoShellConnection because it's a
+// MojoShellConnection::Listener.
+class RenderWidgetWindowTreeClientFactoryImpl
+    : public MojoShellConnection::Listener,
+      public mojo::InterfaceFactory<mojom::RenderWidgetWindowTreeClientFactory>,
+      public mojom::RenderWidgetWindowTreeClientFactory {
+ public:
+  RenderWidgetWindowTreeClientFactoryImpl() {
+    DCHECK(MojoShellConnection::Get());
+    MojoShellConnection::Get()->AddListener(this);
+  }
+
+  ~RenderWidgetWindowTreeClientFactoryImpl() override {}
+
+ private:
+  // MojoShellConnection::Listener implementation:
+  bool ConfigureIncomingConnection(
+      mojo::ApplicationConnection* connection) override {
+    connection->AddService<mojom::RenderWidgetWindowTreeClientFactory>(this);
+    return true;
+  }
+
+  // mojo::InterfaceFactory<mojom::RenderWidgetWindowTreeClientFactory>:
+  void Create(mojo::ApplicationConnection* connection,
+              mojo::InterfaceRequest<mojom::RenderWidgetWindowTreeClientFactory>
+                  request) override {
+    bindings_.AddBinding(this, request.Pass());
+  }
+
+  // mojom::RenderWidgetWindowTreeClientFactory implementation.
+  void CreateWindowTreeClientForRenderWidget(
+      uint32_t routing_id,
+      mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request) override {
+    new RenderWidgetMusConnection(routing_id, request.Pass());
+  }
+
+  mojo::WeakBindingSet<mojom::RenderWidgetWindowTreeClientFactory> bindings_;
+
+  DISALLOW_COPY_AND_ASSIGN(RenderWidgetWindowTreeClientFactoryImpl);
+};
+
+}  // namespace
+
+void CreateRenderWidgetWindowTreeClientFactory() {
+  new RenderWidgetWindowTreeClientFactoryImpl;
+}
+
+}  // namespace content
diff --git a/content/renderer/render_widget_window_tree_client_factory.h b/content/renderer/render_widget_window_tree_client_factory.h
new file mode 100644
index 0000000..09eb36b98
--- /dev/null
+++ b/content/renderer/render_widget_window_tree_client_factory.h
@@ -0,0 +1,14 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_
+#define CONTENT_RENDERER_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_
+
+namespace content {
+
+void CreateRenderWidgetWindowTreeClientFactory();
+
+}  // namespace content
+
+#endif  // CONTENT_RENDERER_RENDER_WIDGET_WINDOW_TREE_CLIENT_FACTORY_H_
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc
index ea7c913..8fb158d 100644
--- a/content/renderer/renderer_main.cc
+++ b/content/renderer/renderer_main.cc
@@ -58,6 +58,10 @@
 #include "ui/ozone/public/client_native_pixmap_factory.h"
 #endif
 
+#if defined(MOJO_SHELL_CLIENT)
+#include "content/common/mojo/mojo_shell_connection_impl.h"
+#endif
+
 namespace content {
 namespace {
 // This function provides some ways to test crash and assertion handling
@@ -90,6 +94,10 @@
   base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
       kTraceEventRendererProcessSortIndex);
 
+#if defined(MOJO_SHELL_CLIENT)
+  MojoShellConnectionImpl::Create();
+#endif
+
   const base::CommandLine& parsed_command_line = parameters.command_line;
 
 #if defined(OS_MACOSX)
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc
index 793a68a0..e6c175c 100644
--- a/extensions/browser/api/web_request/web_request_api.cc
+++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -5,12 +5,14 @@
 #include "extensions/browser/api/web_request/web_request_api.h"
 
 #include <algorithm>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/json/json_writer.h"
 #include "base/lazy_instance.h"
 #include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/metrics/histogram.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -249,7 +251,7 @@
     keys::kRequestBodyRawKey
   };
 
-  const ScopedVector<net::UploadElementReader>* readers =
+  const std::vector<scoped_ptr<net::UploadElementReader>>* readers =
       upload_data->GetElementReaders();
   bool some_succeeded = false;
   if (readers) {
diff --git a/google_apis/drive/drive_api_requests_unittest.cc b/google_apis/drive/drive_api_requests_unittest.cc
index 817fffa..1df9680 100644
--- a/google_apis/drive/drive_api_requests_unittest.cc
+++ b/google_apis/drive/drive_api_requests_unittest.cc
@@ -160,7 +160,7 @@
 
     GURL test_base_url = test_util::GetBaseUrlForTesting(test_server_.port());
     url_generator_.reset(
-        new DriveApiUrlGenerator(test_base_url, test_base_url));
+        new DriveApiUrlGenerator(test_base_url, test_base_url, test_base_url));
 
     // Reset the server's expected behavior just in case.
     ResetExpectedResponse();
diff --git a/google_apis/drive/drive_api_url_generator.cc b/google_apis/drive/drive_api_url_generator.cc
index 14da8a3a..a097527b 100644
--- a/google_apis/drive/drive_api_url_generator.cc
+++ b/google_apis/drive/drive_api_url_generator.cc
@@ -32,7 +32,8 @@
 const char kDriveV2BatchUploadUrl[] = "upload/drive";
 const char kDriveV2PermissionsUrlFormat[] = "drive/v2/files/%s/permissions";
 const char kDriveV2DownloadUrlFormat[] = "host/%s";
-const char kDriveV2ThumbnailUrlFormat[] = "thumb/%s?width=%d&height=%d";
+const char kDriveV2ThumbnailUrlFormat[] = "d/%s=w%d-h%d";
+const char kDriveV2ThumbnailUrlWithCropFormat[] = "d/%s=w%d-h%d-c";
 
 // apps.delete and file.authorize API is exposed through a special endpoint
 // v2internal that is accessible only by the official API key for Chrome.
@@ -53,9 +54,11 @@
 }  // namespace
 
 DriveApiUrlGenerator::DriveApiUrlGenerator(const GURL& base_url,
-                                           const GURL& base_download_url)
+                                           const GURL& base_download_url,
+                                           const GURL& base_thumbnail_url)
     : base_url_(base_url),
-      base_download_url_(base_download_url) {
+      base_download_url_(base_download_url),
+      base_thumbnail_url_(base_thumbnail_url) {
   // Do nothing.
 }
 
@@ -73,6 +76,9 @@
     "https://www.googledrive.com";
 #endif
 
+const char DriveApiUrlGenerator::kBaseThumbnailUrlForProduction[] =
+    "https://lh3.googleusercontent.com";
+
 GURL DriveApiUrlGenerator::GetAboutGetUrl() const {
   return base_url_.Resolve(kDriveV2AboutUrl);
 }
@@ -298,15 +304,10 @@
                                            int width,
                                            int height,
                                            bool crop) const {
-  GURL url = base_download_url_.Resolve(
-      base::StringPrintf(kDriveV2ThumbnailUrlFormat,
-                         net::EscapePath(resource_id).c_str(), width, height));
-
-  // crop is "false" by default.
-  if (crop)
-    url = net::AppendOrReplaceQueryParameter(url, "crop", "true");
-
-  return url;
+  return base_thumbnail_url_.Resolve(
+    base::StringPrintf(
+        crop ? kDriveV2ThumbnailUrlWithCropFormat : kDriveV2ThumbnailUrlFormat,
+        net::EscapePath(resource_id).c_str(), width, height));
 }
 
 GURL DriveApiUrlGenerator::GetBatchUploadUrl() const {
diff --git a/google_apis/drive/drive_api_url_generator.h b/google_apis/drive/drive_api_url_generator.h
index 7e498fb..67f402f6 100644
--- a/google_apis/drive/drive_api_url_generator.h
+++ b/google_apis/drive/drive_api_url_generator.h
@@ -17,7 +17,9 @@
  public:
   // |base_url| is the path to the target drive api server.
   // Note that this is an injecting point for a testing server.
-  DriveApiUrlGenerator(const GURL& base_url, const GURL& base_download_url);
+  DriveApiUrlGenerator(const GURL& base_url,
+                       const GURL& base_download_url,
+                       const GURL& base_thumbnail_url);
   ~DriveApiUrlGenerator();
 
   // The base URL for communicating with the production drive api server.
@@ -26,6 +28,9 @@
   // The base URL for the file download server for production.
   static const char kBaseDownloadUrlForProduction[];
 
+  // The base URL for the thumbnail download server for production.
+  static const char kBaseThumbnailUrlForProduction[];
+
   // Returns a URL to invoke "About: get" method.
   GURL GetAboutGetUrl() const;
 
@@ -121,6 +126,7 @@
  private:
   const GURL base_url_;
   const GURL base_download_url_;
+  const GURL base_thumbnail_url_;
 
   // This class is copyable hence no DISALLOW_COPY_AND_ASSIGN here.
 };
diff --git a/google_apis/drive/drive_api_url_generator_unittest.cc b/google_apis/drive/drive_api_url_generator_unittest.cc
index 28e79c45..1240b24 100644
--- a/google_apis/drive/drive_api_url_generator_unittest.cc
+++ b/google_apis/drive/drive_api_url_generator_unittest.cc
@@ -15,13 +15,15 @@
 // OS, so use testing base urls.
 const char kBaseUrlForTesting[] = "https://www.example.com";
 const char kBaseDownloadUrlForTesting[] = "https://download.example.com/p/";
+const char kBaseThumbnailUrlForTesting[] = "https://thumbnail.example.com";
 }  // namespace
 
 class DriveApiUrlGeneratorTest : public testing::Test {
  public:
   DriveApiUrlGeneratorTest()
       : url_generator_(GURL(kBaseUrlForTesting),
-                       GURL(kBaseDownloadUrlForTesting)) {}
+                       GURL(kBaseDownloadUrlForTesting),
+                       GURL(kBaseThumbnailUrlForTesting)) {}
 
  protected:
   DriveApiUrlGenerator url_generator_;
@@ -369,13 +371,12 @@
 
 TEST_F(DriveApiUrlGeneratorTest, GenerateThumbnailUrl) {
   EXPECT_EQ(
-      "https://download.example.com/p/thumb/0ADK06pfg?width=500&height=500",
-      url_generator_.GetThumbnailUrl("0ADK06pfg", 500, 500, false).spec());
+      "https://thumbnail.example.com/d/0ADK06pfg=w500-h480",
+      url_generator_.GetThumbnailUrl("0ADK06pfg", 500, 480, false).spec());
 
   EXPECT_EQ(
-      "https://download.example.com/p/thumb/"
-      "0ADK06pfg?width=360&height=360&crop=true",
-      url_generator_.GetThumbnailUrl("0ADK06pfg", 360, 360, true).spec());
+      "https://thumbnail.example.com/d/0ADK06pfg=w360-h380-c",
+      url_generator_.GetThumbnailUrl("0ADK06pfg", 360, 380, true).spec());
 }
 
 TEST_F(DriveApiUrlGeneratorTest, BatchUploadUrl) {
diff --git a/google_apis/drive/files_list_request_runner_unittest.cc b/google_apis/drive/files_list_request_runner_unittest.cc
index d8d8e78..51b72c6 100644
--- a/google_apis/drive/files_list_request_runner_unittest.cc
+++ b/google_apis/drive/files_list_request_runner_unittest.cc
@@ -78,7 +78,8 @@
     runner_.reset(new FilesListRequestRunner(
         request_sender_.get(),
         google_apis::DriveApiUrlGenerator(test_server_.base_url(),
-                                          test_server_.GetURL("/download/"))));
+                                          test_server_.GetURL("/download/"),
+                                          test_server_.GetURL("/thumbnail/"))));
   }
 
   void TearDown() override {
diff --git a/ios/chrome/browser/application_context.h b/ios/chrome/browser/application_context.h
index d34d4afa..2c02c2e 100644
--- a/ios/chrome/browser/application_context.h
+++ b/ios/chrome/browser/application_context.h
@@ -9,6 +9,10 @@
 
 #include "base/macros.h"
 
+namespace gcm {
+class GCMDriver;
+}
+
 namespace ios {
 class ChromeBrowserStateManager;
 }
@@ -37,6 +41,10 @@
 class VariationsService;
 }
 
+namespace web_resource {
+class PromoResourceService;
+}
+
 class ApplicationContext;
 class IOSChromeIOThread;
 class PrefService;
@@ -92,6 +100,12 @@
   // Gets the IOSChromeIOThread.
   virtual IOSChromeIOThread* GetIOSChromeIOThread() = 0;
 
+  // Gets the GCMDriver.
+  virtual gcm::GCMDriver* GetGCMDriver() = 0;
+
+  // Gets the PromoResourceService.
+  virtual web_resource::PromoResourceService* GetPromoResourceService() = 0;
+
  protected:
   // Sets the global ApplicationContext instance.
   static void SetApplicationContext(ApplicationContext* context);
diff --git a/ios/chrome/browser/application_context_impl.cc b/ios/chrome/browser/application_context_impl.cc
index f7351837..34833add 100644
--- a/ios/chrome/browser/application_context_impl.cc
+++ b/ios/chrome/browser/application_context_impl.cc
@@ -15,6 +15,9 @@
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
 #include "base/time/default_tick_clock.h"
+#include "components/gcm_driver/gcm_client_factory.h"
+#include "components/gcm_driver/gcm_desktop_utils.h"
+#include "components/gcm_driver/gcm_driver.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/keyed_service/core/service_access_type.h"
 #include "components/metrics/metrics_pref_names.h"
@@ -23,20 +26,32 @@
 #include "components/network_time/network_time_tracker.h"
 #include "components/translate/core/browser/translate_download_manager.h"
 #include "components/variations/service/variations_service.h"
+#include "components/web_resource/promo_resource_service.h"
 #include "components/web_resource/web_resource_pref_names.h"
 #include "ios/chrome/browser/chrome_paths.h"
+#include "ios/chrome/browser/chrome_switches.h"
 #include "ios/chrome/browser/history/history_service_factory.h"
 #include "ios/chrome/browser/ios_chrome_io_thread.h"
 #include "ios/chrome/browser/pref_names.h"
 #include "ios/chrome/browser/prefs/browser_prefs.h"
 #include "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h"
+#include "ios/chrome/browser/web_resource/web_resource_util.h"
 #include "ios/chrome/common/channel_info.h"
 #include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state_manager.h"
 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
+#include "ios/web/public/web_thread.h"
 #include "net/log/net_log_capture_mode.h"
 #include "net/socket/client_socket_pool_manager.h"
 
+namespace {
+
+// Dummy flag because iOS does not support disabling background networking.
+extern const char kDummyDisableBackgroundNetworking[] =
+    "dummy-disable-background-networking";
+
+}
+
 ApplicationContextImpl::ApplicationContextImpl(
     base::SequencedTaskRunner* local_state_task_runner,
     const base::CommandLine& command_line,
@@ -77,10 +92,28 @@
 
 void ApplicationContextImpl::PreMainMessageLoopRun() {
   DCHECK(thread_checker_.CalledOnValidThread());
+  const base::CommandLine& command_line =
+      *base::CommandLine::ForCurrentProcess();
+  if (!command_line.HasSwitch(switches::kDisableIOSWebResources)) {
+    DCHECK(!promo_resource_service_.get());
+    promo_resource_service_.reset(new web_resource::PromoResourceService(
+        GetLocalState(), ::GetChannel(), GetApplicationLocale(),
+        GetSystemURLRequestContext(), kDummyDisableBackgroundNetworking,
+        web_resource::GetIOSChromeParseJSONCallback()));
+    promo_resource_service_->StartAfterDelay();
+  }
 }
 
 void ApplicationContextImpl::StartTearDown() {
   DCHECK(thread_checker_.CalledOnValidThread());
+  // PromoResourceService must be destroyed after the keyed services and before
+  // the IO thread.
+  promo_resource_service_.reset();
+
+  // The |gcm_driver_| must shut down while the IO thread is still alive.
+  if (gcm_driver_)
+    gcm_driver_->Shutdown();
+
   if (local_state_) {
     local_state_->CommitPendingWrite();
   }
@@ -213,6 +246,20 @@
   return ios_chrome_io_thread_.get();
 }
 
+gcm::GCMDriver* ApplicationContextImpl::GetGCMDriver() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!gcm_driver_)
+    CreateGCMDriver();
+  DCHECK(gcm_driver_);
+  return gcm_driver_.get();
+}
+
+web_resource::PromoResourceService*
+ApplicationContextImpl::GetPromoResourceService() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  return promo_resource_service_.get();
+}
+
 void ApplicationContextImpl::SetApplicationLocale(const std::string& locale) {
   DCHECK(thread_checker_.CalledOnValidThread());
   application_locale_ = locale;
@@ -247,3 +294,23 @@
         local_state_->GetBoolean(prefs::kLastSessionExitedCleanly);
   }
 }
+
+void ApplicationContextImpl::CreateGCMDriver() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(!gcm_driver_);
+
+  base::FilePath store_path;
+  CHECK(PathService::Get(ios::DIR_GLOBAL_GCM_STORE, &store_path));
+  base::SequencedWorkerPool* worker_pool = web::WebThread::GetBlockingPool();
+  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner(
+      worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
+          worker_pool->GetSequenceToken(),
+          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
+
+  gcm_driver_ = gcm::CreateGCMDriverDesktop(
+      make_scoped_ptr(new gcm::GCMClientFactory), GetLocalState(), store_path,
+      GetSystemURLRequestContext(), ::GetChannel(),
+      web::WebThread::GetTaskRunnerForThread(web::WebThread::UI),
+      web::WebThread::GetTaskRunnerForThread(web::WebThread::IO),
+      blocking_task_runner);
+}
diff --git a/ios/chrome/browser/application_context_impl.h b/ios/chrome/browser/application_context_impl.h
index e3da75d..39d1de5 100644
--- a/ios/chrome/browser/application_context_impl.h
+++ b/ios/chrome/browser/application_context_impl.h
@@ -58,6 +58,8 @@
   net_log::ChromeNetLog* GetNetLog() override;
   network_time::NetworkTimeTracker* GetNetworkTimeTracker() override;
   IOSChromeIOThread* GetIOSChromeIOThread() override;
+  gcm::GCMDriver* GetGCMDriver() override;
+  web_resource::PromoResourceService* GetPromoResourceService() override;
 
  private:
   // Sets the locale used by the application.
@@ -66,11 +68,16 @@
   // Create the local state.
   void CreateLocalState();
 
+  // Create the gcm driver.
+  void CreateGCMDriver();
+
   base::ThreadChecker thread_checker_;
   scoped_ptr<PrefService> local_state_;
   scoped_ptr<net_log::ChromeNetLog> net_log_;
   scoped_ptr<network_time::NetworkTimeTracker> network_time_tracker_;
   scoped_ptr<IOSChromeIOThread> ios_chrome_io_thread_;
+  scoped_ptr<gcm::GCMDriver> gcm_driver_;
+  scoped_ptr<web_resource::PromoResourceService> promo_resource_service_;
   std::string application_locale_;
 
   // Sequenced task runner for local state related I/O tasks.
diff --git a/ios/chrome/browser/chrome_switches.cc b/ios/chrome/browser/chrome_switches.cc
index c069fd53..47711ff 100644
--- a/ios/chrome/browser/chrome_switches.cc
+++ b/ios/chrome/browser/chrome_switches.cc
@@ -27,6 +27,9 @@
 const char kDisableIOSPasswordSuggestions[] =
     "disable-ios-password-suggestions";
 
+// Disables the backend service for web resources.
+const char kDisableIOSWebResources[] = "disable-web-resources";
+
 // Disables the use of WKWebView instead of UIWebView.
 const char kDisableIOSWKWebView[] = "disable-wkwebview";
 
diff --git a/ios/chrome/browser/chrome_switches.h b/ios/chrome/browser/chrome_switches.h
index f7eea29..9436fb05 100644
--- a/ios/chrome/browser/chrome_switches.h
+++ b/ios/chrome/browser/chrome_switches.h
@@ -13,6 +13,7 @@
 extern const char kDisableIOSFastWebScrollViewInsets[];
 extern const char kDisableIOSPasswordGeneration[];
 extern const char kDisableIOSPasswordSuggestions[];
+extern const char kDisableIOSWebResources[];
 extern const char kDisableIOSWKWebView[];
 extern const char kDisableKeyboardCommands[];
 extern const char kDisableNTPFavicons[];
diff --git a/ios/chrome/test/testing_application_context.cc b/ios/chrome/test/testing_application_context.cc
index 2623244..3861344 100644
--- a/ios/chrome/test/testing_application_context.cc
+++ b/ios/chrome/test/testing_application_context.cc
@@ -115,3 +115,14 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   return nullptr;
 }
+
+gcm::GCMDriver* TestingApplicationContext::GetGCMDriver() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  return nullptr;
+}
+
+web_resource::PromoResourceService*
+TestingApplicationContext::GetPromoResourceService() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  return nullptr;
+}
diff --git a/ios/chrome/test/testing_application_context.h b/ios/chrome/test/testing_application_context.h
index 949c60c9..beda41a9 100644
--- a/ios/chrome/test/testing_application_context.h
+++ b/ios/chrome/test/testing_application_context.h
@@ -42,6 +42,8 @@
   net_log::ChromeNetLog* GetNetLog() override;
   network_time::NetworkTimeTracker* GetNetworkTimeTracker() override;
   IOSChromeIOThread* GetIOSChromeIOThread() override;
+  gcm::GCMDriver* GetGCMDriver() override;
+  web_resource::PromoResourceService* GetPromoResourceService() override;
 
  private:
   base::ThreadChecker thread_checker_;
diff --git a/ios/net/crn_http_protocol_handler.mm b/ios/net/crn_http_protocol_handler.mm
index ba7ca57d..05609b0 100644
--- a/ios/net/crn_http_protocol_handler.mm
+++ b/ios/net/crn_http_protocol_handler.mm
@@ -4,11 +4,14 @@
 
 #import "ios/net/crn_http_protocol_handler.h"
 
+#include <vector>
+
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/mac/bind_objc_block.h"
 #include "base/mac/scoped_nsobject.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
@@ -193,7 +196,7 @@
   // Stream delegate to read the HTTPBodyStream.
   base::scoped_nsobject<CRWHTTPStreamDelegate> stream_delegate_;
   // Vector of readers used to accumulate a POST data stream.
-  ScopedVector<UploadElementReader> post_data_readers_;
+  std::vector<scoped_ptr<UploadElementReader>> post_data_readers_;
 
   // This cannot be a scoped pointer because it must be deleted on the IO
   // thread.
@@ -238,7 +241,7 @@
         // NOTE: This call will result in |post_data_readers_| being cleared,
         // which is the desired behavior.
         net_request_->set_upload(make_scoped_ptr(
-            new ElementsUploadDataStream(post_data_readers_.Pass(), 0)));
+            new ElementsUploadDataStream(std::move(post_data_readers_), 0)));
         DCHECK(post_data_readers_.empty());
       }
       net_request_->Start();
@@ -253,7 +256,7 @@
       if (length) {
         std::vector<char> owned_data(buffer_->data(), buffer_->data() + length);
         post_data_readers_.push_back(
-            new UploadOwnedBytesElementReader(&owned_data));
+            make_scoped_ptr(new UploadOwnedBytesElementReader(&owned_data)));
       }
       break;
     }
diff --git a/mash/wm/BUILD.gn b/mash/wm/BUILD.gn
index 3cad781..30f27cc7 100644
--- a/mash/wm/BUILD.gn
+++ b/mash/wm/BUILD.gn
@@ -40,6 +40,8 @@
     "non_client_frame_controller.h",
     "property_util.cc",
     "property_util.h",
+    "shadow.cc",
+    "shadow.h",
     "shelf_layout.cc",
     "shelf_layout.h",
     "window_layout.cc",
@@ -68,6 +70,7 @@
     "//ui/gfx",
     "//ui/gfx/geometry",
     "//ui/mojo/init",
+    "//ui/resources",
     "//ui/strings",
     "//ui/views",
     "//ui/views/mus:for_mojo_application",
diff --git a/mash/wm/non_client_frame_controller.cc b/mash/wm/non_client_frame_controller.cc
index 3009fc46..54471b68 100644
--- a/mash/wm/non_client_frame_controller.cc
+++ b/mash/wm/non_client_frame_controller.cc
@@ -5,16 +5,84 @@
 #include "mash/wm/non_client_frame_controller.h"
 
 #include "components/mus/public/cpp/window.h"
+#include "components/mus/public/interfaces/window_tree_host.mojom.h"
 #include "mash/wm/frame/non_client_frame_view_mash.h"
 #include "mash/wm/property_util.h"
+#include "mash/wm/shadow.h"
+#include "mojo/converters/geometry/geometry_type_converters.h"
+#include "ui/aura/layout_manager.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/compositor/layer.h"
 #include "ui/views/mus/native_widget_mus.h"
 #include "ui/views/widget/widget.h"
 
 namespace mash {
 namespace wm {
-
 namespace {
 
+enum class ShadowStyle {
+  NORMAL,
+  SMALL,
+};
+
+// LayoutManager associated with the window created by WindowTreeHost. Resizes
+// all children of the parent to match the bounds of the parent. Additionally
+// handles sizing of a Shadow.
+class ContentWindowLayoutManager : public aura::LayoutManager {
+ public:
+  explicit ContentWindowLayoutManager(aura::Window* window,
+                                      ShadowStyle style,
+                                      Shadow* shadow)
+      : window_(window), style_(style), shadow_(shadow) {
+    OnWindowResized();
+  }
+  ~ContentWindowLayoutManager() override {}
+
+  void SetShadow(Shadow* shadow) {
+    shadow_ = shadow;
+    if (shadow_)
+      shadow_->SetContentBounds(child_bounds());
+  }
+
+ private:
+  // Bounds for child windows.
+  gfx::Rect child_bounds() const {
+    return gfx::Rect(0, 0, window_->bounds().size().width(),
+                     window_->bounds().size().height());
+  }
+
+  void UpdateChildBounds(aura::Window* child) {
+    child->SetBounds(child_bounds());
+  }
+
+  // aura::LayoutManager:
+  void OnWindowResized() override {
+    for (aura::Window* child : window_->children())
+      UpdateChildBounds(child);
+    // Shadow takes care of resizing the layer appropriately.
+    if (shadow_)
+      shadow_->SetContentBounds(child_bounds());
+  }
+  void OnWindowAddedToLayout(aura::Window* child) override {
+    UpdateChildBounds(child);
+  }
+  void OnWillRemoveWindowFromLayout(aura::Window* child) override {}
+  void OnWindowRemovedFromLayout(aura::Window* child) override {}
+  void OnChildWindowVisibilityChanged(aura::Window* child,
+                                      bool visible) override {}
+  void SetChildBounds(aura::Window* child,
+                      const gfx::Rect& requested_bounds) override {
+    SetChildBoundsDirect(child, requested_bounds);
+  }
+
+  aura::Window* window_;
+  const ShadowStyle style_;
+  Shadow* shadow_;
+
+  DISALLOW_COPY_AND_ASSIGN(ContentWindowLayoutManager);
+};
+
 class WmNativeWidgetMus : public views::NativeWidgetMus {
  public:
   WmNativeWidgetMus(views::internal::NativeWidgetDelegate* delegate,
@@ -34,6 +102,21 @@
         new NonClientFrameViewMash(widget, window());
     return frame_view;
   }
+  void InitNativeWidget(const views::Widget::InitParams& params) override {
+    views::NativeWidgetMus::InitNativeWidget(params);
+    aura::WindowTreeHost* window_tree_host = GetNativeView()->GetHost();
+    // TODO(sky): shadow should be determined by window type.
+    shadow_.reset(new Shadow);
+    shadow_->Init(Shadow::STYLE_ACTIVE);
+    ContentWindowLayoutManager* layout_manager = new ContentWindowLayoutManager(
+        window_tree_host->window(), ShadowStyle::NORMAL, shadow_.get());
+    window_tree_host->window()->SetLayoutManager(layout_manager);
+    const int inset = Shadow::GetInteriorInsetForStyle(Shadow::STYLE_ACTIVE);
+    window_tree_host->SetOutputSurfacePadding(
+        gfx::Insets(inset, inset, inset, inset));
+    window_tree_host->window()->layer()->Add(shadow_->layer());
+    shadow_->layer()->parent()->StackAtBottom(shadow_->layer());
+  }
   void CenterWindow(const gfx::Size& size) override {
     // Do nothing. The client controls the size, not us.
   }
@@ -43,14 +126,21 @@
   }
 
  private:
+  // The shadow, may be null.
+  scoped_ptr<Shadow> shadow_;
+
   DISALLOW_COPY_AND_ASSIGN(WmNativeWidgetMus);
 };
 
 }  // namespace
 
-NonClientFrameController::NonClientFrameController(mojo::Shell* shell,
-                                                   mus::Window* window)
-    : widget_(new views::Widget), window_(window) {
+NonClientFrameController::NonClientFrameController(
+    mojo::Shell* shell,
+    mus::Window* window,
+    mus::mojom::WindowTreeHost* window_tree_host)
+    : widget_(new views::Widget),
+      window_(window),
+      mus_window_tree_host_(window_tree_host) {
   window_->AddObserver(this);
 
   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
@@ -58,6 +148,12 @@
   params.native_widget = new WmNativeWidgetMus(widget_, shell, window);
   widget_->Init(params);
   widget_->Show();
+
+  const int shadow_inset =
+      Shadow::GetInteriorInsetForStyle(Shadow::STYLE_ACTIVE);
+  mus_window_tree_host_->SetUnderlaySurfaceOffsetAndExtendedHitArea(
+      window->id(), shadow_inset, shadow_inset,
+      mojo::Insets::From(gfx::Insets()));
 }
 
 // static
diff --git a/mash/wm/non_client_frame_controller.h b/mash/wm/non_client_frame_controller.h
index 9e4d121..492500d 100644
--- a/mash/wm/non_client_frame_controller.h
+++ b/mash/wm/non_client_frame_controller.h
@@ -19,6 +19,9 @@
 
 namespace mus {
 class Window;
+namespace mojom {
+class WindowTreeHost;
+}
 }
 
 namespace mash {
@@ -29,7 +32,9 @@
                                  public mus::WindowObserver {
  public:
   // NonClientFrameController deletes itself when |window| is destroyed.
-  NonClientFrameController(mojo::Shell* shell, mus::Window* window);
+  NonClientFrameController(mojo::Shell* shell,
+                           mus::Window* window,
+                           mus::mojom::WindowTreeHost* window_tree_host);
 
   // Returns the preferred client area insets.
   static gfx::Insets GetPreferredClientAreaInsets();
@@ -57,6 +62,8 @@
   // is null.
   mus::Window* window_;
 
+  mus::mojom::WindowTreeHost* mus_window_tree_host_;
+
   DISALLOW_COPY_AND_ASSIGN(NonClientFrameController);
 };
 
diff --git a/mash/wm/shadow.cc b/mash/wm/shadow.cc
new file mode 100644
index 0000000..07a1809
--- /dev/null
+++ b/mash/wm/shadow.cc
@@ -0,0 +1,196 @@
+// 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 "mash/wm/shadow.h"
+
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/compositor/layer.h"
+#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/resources/grit/ui_resources.h"
+
+namespace mash {
+namespace wm {
+
+namespace {
+
+// The opacity used for active shadow when animating between
+// inactive/active shadow.
+const float kInactiveShadowAnimationOpacity = 0.2f;
+
+// Shadow aperture for different styles.
+// Note that this may be greater than interior inset to allow shadows with
+// curved corners that extend inwards beyond a window's borders.
+const int kActiveInteriorAperture = 134;
+const int kInactiveInteriorAperture = 134;
+const int kSmallInteriorAperture = 9;
+
+// Interior inset for different styles.
+const int kActiveInteriorInset = 64;
+const int kInactiveInteriorInset = 64;
+const int kSmallInteriorInset = 4;
+
+// Duration for opacity animation in milliseconds.
+const int kShadowAnimationDurationMs = 100;
+
+int GetShadowApertureForStyle(wm::Shadow::Style style) {
+  switch (style) {
+    case wm::Shadow::STYLE_ACTIVE:
+      return kActiveInteriorAperture;
+    case wm::Shadow::STYLE_INACTIVE:
+      return kInactiveInteriorAperture;
+    case wm::Shadow::STYLE_SMALL:
+      return kSmallInteriorAperture;
+  }
+  return 0;
+}
+
+}  // namespace
+
+Shadow::Shadow() : style_(STYLE_ACTIVE), interior_inset_(0) {
+}
+
+Shadow::~Shadow() {
+}
+
+void Shadow::Init(Style style) {
+  style_ = style;
+
+  layer_.reset(new ui::Layer(ui::LAYER_NOT_DRAWN));
+  shadow_layer_.reset(new ui::Layer(ui::LAYER_NINE_PATCH));
+  layer()->Add(shadow_layer_.get());
+
+  UpdateImagesForStyle();
+  shadow_layer_->set_name("Shadow");
+  shadow_layer_->SetVisible(true);
+  shadow_layer_->SetFillsBoundsOpaquely(false);
+}
+
+// static
+int Shadow::GetInteriorInsetForStyle(Shadow::Style style) {
+  switch (style) {
+    case Shadow::STYLE_ACTIVE:
+      return kActiveInteriorInset;
+    case Shadow::STYLE_INACTIVE:
+      return kInactiveInteriorInset;
+    case Shadow::STYLE_SMALL:
+      return kSmallInteriorInset;
+  }
+  return 0;
+}
+
+void Shadow::SetContentBounds(const gfx::Rect& content_bounds) {
+  content_bounds_ = content_bounds;
+  UpdateLayerBounds();
+}
+
+void Shadow::SetStyle(Style style) {
+  if (style_ == style)
+    return;
+
+  Style old_style = style_;
+  style_ = style;
+
+  // Stop waiting for any as yet unfinished implicit animations.
+  StopObservingImplicitAnimations();
+
+  // If we're switching to or from the small style, don't bother with
+  // animations.
+  if (style == STYLE_SMALL || old_style == STYLE_SMALL) {
+    UpdateImagesForStyle();
+    // Make sure the shadow is fully opaque.
+    shadow_layer_->SetOpacity(1.0f);
+    return;
+  }
+
+  // If we're becoming active, switch images now.  Because the inactive image
+  // has a very low opacity the switch isn't noticeable and this approach
+  // allows us to use only a single set of shadow images at a time.
+  if (style == STYLE_ACTIVE) {
+    UpdateImagesForStyle();
+    // Opacity was baked into inactive image, start opacity low to match.
+    shadow_layer_->SetOpacity(kInactiveShadowAnimationOpacity);
+  }
+
+  {
+    // Property sets within this scope will be implicitly animated.
+    ui::ScopedLayerAnimationSettings settings(shadow_layer_->GetAnimator());
+    settings.AddObserver(this);
+    settings.SetTransitionDuration(
+        base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs));
+    switch (style_) {
+      case STYLE_ACTIVE:
+        // Animate the active shadow from kInactiveShadowAnimationOpacity to
+        // 1.0f.
+        shadow_layer_->SetOpacity(1.0f);
+        break;
+      case STYLE_INACTIVE:
+        // The opacity will be reset to 1.0f when animation is completed.
+        shadow_layer_->SetOpacity(kInactiveShadowAnimationOpacity);
+        break;
+      default:
+        NOTREACHED() << "Unhandled style " << style_;
+        break;
+    }
+  }
+}
+
+void Shadow::OnImplicitAnimationsCompleted() {
+  // If we just finished going inactive, switch images.  This doesn't cause
+  // a visual pop because the inactive image opacity is so low.
+  if (style_ == STYLE_INACTIVE) {
+    UpdateImagesForStyle();
+    // Opacity is baked into inactive image, so set fully opaque.
+    shadow_layer_->SetOpacity(1.0f);
+  }
+}
+
+void Shadow::UpdateImagesForStyle() {
+  ResourceBundle& res = ResourceBundle::GetSharedInstance();
+  gfx::Image image;
+  switch (style_) {
+    case STYLE_ACTIVE:
+      image = res.GetImageNamed(IDR_AURA_SHADOW_ACTIVE);
+      break;
+    case STYLE_INACTIVE:
+      image = res.GetImageNamed(IDR_AURA_SHADOW_INACTIVE);
+      break;
+    case STYLE_SMALL:
+      image = res.GetImageNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL);
+      break;
+    default:
+      NOTREACHED() << "Unhandled style " << style_;
+      break;
+  }
+
+  shadow_layer_->UpdateNinePatchLayerImage(image.AsImageSkia());
+  image_size_ = image.Size();
+  interior_inset_ = GetInteriorInsetForStyle(style_);
+
+  // Image sizes may have changed.
+  UpdateLayerBounds();
+}
+
+void Shadow::UpdateLayerBounds() {
+  // Update bounds based on content bounds and interior inset.
+  gfx::Rect layer_bounds = content_bounds_;
+  layer_bounds.Inset(-interior_inset_, -interior_inset_);
+  layer()->SetBounds(layer_bounds);
+  shadow_layer_->SetBounds(gfx::Rect(layer_bounds.size()));
+
+  // Update the shadow aperture and border for style. Note that border is in
+  // layer space and it cannot exceed the bounds of the layer.
+  int aperture = GetShadowApertureForStyle(style_);
+  int aperture_x = std::min(aperture, layer_bounds.width() / 2);
+  int aperture_y = std::min(aperture, layer_bounds.height() / 2);
+  shadow_layer_->UpdateNinePatchLayerAperture(
+      gfx::Rect(aperture_x, aperture_y,
+                image_size_.width() - aperture_x * 2,
+                image_size_.height() - aperture_y * 2));
+  shadow_layer_->UpdateNinePatchLayerBorder(
+      gfx::Rect(aperture_x, aperture_y, aperture_x * 2, aperture_y * 2));
+}
+
+}  // namespace wm
+}  // namespace mash
diff --git a/mash/wm/shadow.h b/mash/wm/shadow.h
new file mode 100644
index 0000000..db8aa0c
--- /dev/null
+++ b/mash/wm/shadow.h
@@ -0,0 +1,100 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MASH_WM_SHADOW_H_
+#define MASH_WM_SHADOW_H_
+
+#include "base/basictypes.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/compositor/layer_animation_observer.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace ui {
+class Layer;
+}  // namespace ui
+
+namespace mash {
+namespace wm {
+
+// Simple class that draws a drop shadow around content at given bounds.
+class Shadow : public ui::ImplicitAnimationObserver {
+ public:
+  enum Style {
+    // Active windows have more opaque shadows, shifted down to make the window
+    // appear "higher".
+    STYLE_ACTIVE,
+
+    // Inactive windows have less opaque shadows.
+    STYLE_INACTIVE,
+
+    // Small windows like tooltips and context menus have lighter, smaller
+    // shadows.
+    STYLE_SMALL,
+  };
+
+  Shadow();
+  ~Shadow() override;
+
+  void Init(Style style);
+
+  // Returns the interio inset for the specified style. The interior inset
+  // is the amount of padding added to each side of the content bounds that the
+  // shadow renders into. In other words the shadow extends from all sides of
+  // the layer by this value.
+  static int GetInteriorInsetForStyle(Style style);
+
+  // Returns |layer_.get()|. This is exposed so it can be added to the same
+  // layer as the content and stacked below it.  SetContentBounds() should be
+  // used to adjust the shadow's size and position (rather than applying
+  // transformations to this layer).
+  ui::Layer* layer() const { return layer_.get(); }
+
+  const gfx::Rect& content_bounds() const { return content_bounds_; }
+  Style style() const { return style_; }
+
+  // Moves and resizes the shadow layer to frame |content_bounds|.
+  void SetContentBounds(const gfx::Rect& content_bounds);
+
+  // Sets the shadow's style, animating opacity as necessary.
+  void SetStyle(Style style);
+
+  // ui::ImplicitAnimationObserver overrides:
+  void OnImplicitAnimationsCompleted() override;
+
+ private:
+  // Updates the shadow images to the current |style_|.
+  void UpdateImagesForStyle();
+
+  // Updates the shadow layer bounds based on the inteior inset and the current
+  // |content_bounds_|.
+  void UpdateLayerBounds();
+
+  // The current style, set when the transition animation starts.
+  Style style_;
+
+  // The parent layer of the shadow layer. It serves as a container accessible
+  // from the outside to control the visibility of the shadow.
+  scoped_ptr<ui::Layer> layer_;
+
+  // The actual shadow layer corresponding to a cc::NinePatchLayer.
+  scoped_ptr<ui::Layer> shadow_layer_;
+
+  // Size of the current shadow image.
+  gfx::Size image_size_;
+
+  // Bounds of the content that the shadow encloses.
+  gfx::Rect content_bounds_;
+
+  // The interior inset of the shadow images. The content bounds of the image
+  // grid should be set to |content_bounds_| inset by this amount.
+  int interior_inset_;
+
+  DISALLOW_COPY_AND_ASSIGN(Shadow);
+};
+
+}  // namespace wm
+}  // namespace mash
+
+#endif  // MASH_WM_SHADOW_H_
diff --git a/mash/wm/window_manager_application.cc b/mash/wm/window_manager_application.cc
index b86bec5..bc85268 100644
--- a/mash/wm/window_manager_application.cc
+++ b/mash/wm/window_manager_application.cc
@@ -45,7 +45,7 @@
 }
 
 void WindowManagerApplication::AddAccelerators() {
-  host_->AddAccelerator(
+  window_tree_host_->AddAccelerator(
       kWindowSwitchCmd,
       mus::CreateKeyMatcher(mus::mojom::KEYBOARD_CODE_TAB,
                             mus::mojom::EVENT_FLAGS_CONTROL_DOWN));
@@ -61,8 +61,9 @@
       mojo::GetProxy(&window_manager)));
   mus::mojom::WindowTreeHostClientPtr host_client;
   host_client_binding_.Bind(GetProxy(&host_client));
-  mus::CreateSingleWindowTreeHost(app, host_client.Pass(), this, &host_,
-                                  window_manager.Pass(), window_manager_.get());
+  mus::CreateSingleWindowTreeHost(app, host_client.Pass(), this,
+                                  &window_tree_host_, window_manager.Pass(),
+                                  window_manager_.get());
 }
 
 bool WindowManagerApplication::ConfigureIncomingConnection(
@@ -75,7 +76,7 @@
                                              mus::mojom::EventPtr event) {
   switch (id) {
     case kWindowSwitchCmd:
-      host_->ActivateNextWindow();
+      window_tree_host_->ActivateNextWindow();
       break;
     default:
       NOTREACHED() << "Unknown accelerator command: " << id;
@@ -94,7 +95,7 @@
   mus::Window* window = GetWindowForContainer(mojom::CONTAINER_USER_WINDOWS);
   window_layout_.reset(
       new WindowLayout(GetWindowForContainer(mojom::CONTAINER_USER_WINDOWS)));
-  host_->AddActivationParent(window->id());
+  window_tree_host_->AddActivationParent(window->id());
 
   AddAccelerators();
 
diff --git a/mash/wm/window_manager_application.h b/mash/wm/window_manager_application.h
index 8cd4a3d..51c1a227 100644
--- a/mash/wm/window_manager_application.h
+++ b/mash/wm/window_manager_application.h
@@ -57,6 +57,10 @@
 
   mojo::ApplicationImpl* app() { return app_; }
 
+  mus::mojom::WindowTreeHost* window_tree_host() {
+    return window_tree_host_.get();
+  }
+
  private:
   void AddAccelerators();
 
@@ -91,7 +95,7 @@
 
   mojo::TracingImpl tracing_;
 
-  mus::mojom::WindowTreeHostPtr host_;
+  mus::mojom::WindowTreeHostPtr window_tree_host_;
   mojo::Binding<mus::mojom::WindowTreeHostClient> host_client_binding_;
 
   scoped_ptr<ui::mojo::UIInit> ui_init_;
diff --git a/mash/wm/window_manager_impl.cc b/mash/wm/window_manager_impl.cc
index ca88265..761099f 100644
--- a/mash/wm/window_manager_impl.cc
+++ b/mash/wm/window_manager_impl.cc
@@ -79,8 +79,9 @@
   GetContainerForChild(child_window)->AddChild(child_window);
   child_window->Embed(client.Pass());
 
-  // NonClientFrameController deletes itself when the window is destroyed.
-  new NonClientFrameController(state_->app()->shell(), child_window);
+  // NonClientFrameController deletes itself when |child_window| is destroyed.
+  new NonClientFrameController(state_->app()->shell(), child_window,
+                               state_->window_tree_host());
 
   state_->IncrementWindowCount();
 }
diff --git a/media/base/audio_buffer.cc b/media/base/audio_buffer.cc
index 115efa5..168d371e 100644
--- a/media/base/audio_buffer.cc
+++ b/media/base/audio_buffer.cc
@@ -37,7 +37,8 @@
       timestamp_(timestamp),
       duration_(end_of_stream_
                     ? base::TimeDelta()
-                    : CalculateDuration(adjusted_frame_count_, sample_rate_)) {
+                    : CalculateDuration(adjusted_frame_count_, sample_rate_)),
+      data_size_(0) {
   CHECK_GE(channel_count_, 0);
   CHECK_LE(channel_count_, limits::kMaxChannels);
   CHECK_GE(frame_count, 0);
@@ -46,49 +47,46 @@
 
   int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format);
   DCHECK_LE(bytes_per_channel, kChannelAlignment);
-  int data_size = frame_count * bytes_per_channel;
 
   // Empty buffer?
   if (!create_buffer)
     return;
 
-  if (sample_format == kSampleFormatPlanarF32 ||
-      sample_format == kSampleFormatPlanarS16 ||
-      sample_format == kSampleFormatPlanarS32) {
+  int data_size_per_channel = frame_count * bytes_per_channel;
+  if (IsPlanar(sample_format)) {
     // Planar data, so need to allocate buffer for each channel.
     // Determine per channel data size, taking into account alignment.
     int block_size_per_channel =
-        (data_size + kChannelAlignment - 1) & ~(kChannelAlignment - 1);
-    DCHECK_GE(block_size_per_channel, data_size);
+        (data_size_per_channel + kChannelAlignment - 1) &
+        ~(kChannelAlignment - 1);
+    DCHECK_GE(block_size_per_channel, data_size_per_channel);
 
     // Allocate a contiguous buffer for all the channel data.
-    data_.reset(static_cast<uint8*>(base::AlignedAlloc(
-        channel_count_ * block_size_per_channel, kChannelAlignment)));
+    data_size_ = channel_count_ * block_size_per_channel;
+    data_.reset(
+        static_cast<uint8*>(base::AlignedAlloc(data_size_, kChannelAlignment)));
     channel_data_.reserve(channel_count_);
 
     // Copy each channel's data into the appropriate spot.
     for (int i = 0; i < channel_count_; ++i) {
       channel_data_.push_back(data_.get() + i * block_size_per_channel);
       if (data)
-        memcpy(channel_data_[i], data[i], data_size);
+        memcpy(channel_data_[i], data[i], data_size_per_channel);
     }
     return;
   }
 
   // Remaining formats are interleaved data.
-  DCHECK(sample_format_ == kSampleFormatU8 ||
-         sample_format_ == kSampleFormatS16 ||
-         sample_format_ == kSampleFormatS32 ||
-         sample_format_ == kSampleFormatF32) << sample_format_;
+  DCHECK(IsInterleaved(sample_format)) << sample_format_;
   // Allocate our own buffer and copy the supplied data into it. Buffer must
   // contain the data for all channels.
-  data_size *= channel_count_;
+  data_size_ = data_size_per_channel * channel_count_;
   data_.reset(
-      static_cast<uint8*>(base::AlignedAlloc(data_size, kChannelAlignment)));
+      static_cast<uint8*>(base::AlignedAlloc(data_size_, kChannelAlignment)));
   channel_data_.reserve(1);
   channel_data_.push_back(data_.get());
   if (data)
-    memcpy(data_.get(), data[0], data_size);
+    memcpy(data_.get(), data[0], data_size_);
 }
 
 AudioBuffer::~AudioBuffer() {}
diff --git a/media/base/audio_buffer.h b/media/base/audio_buffer.h
index 63390d47..bf8e433 100644
--- a/media/base/audio_buffer.h
+++ b/media/base/audio_buffer.h
@@ -15,9 +15,20 @@
 #include "media/base/media_export.h"
 #include "media/base/sample_format.h"
 
+namespace mojo {
+template <typename T, typename U>
+struct TypeConverter;
+template <typename T>
+class StructPtr;
+};
+
 namespace media {
 class AudioBus;
 
+namespace interfaces {
+class AudioBuffer;
+}
+
 // An audio buffer that takes a copy of the data passed to it, holds it, and
 // copies it into an AudioBus when needed. Also supports an end of stream
 // marker.
@@ -123,6 +134,11 @@
  private:
   friend class base::RefCountedThreadSafe<AudioBuffer>;
 
+  // mojo::TypeConverter added as a friend so that AudioBuffer can be
+  // transferred across a mojo connection.
+  friend struct mojo::TypeConverter<mojo::StructPtr<interfaces::AudioBuffer>,
+                                    scoped_refptr<AudioBuffer>>;
+
   // Allocates aligned contiguous buffer to hold all channel data (1 block for
   // interleaved data, |channel_count| blocks for planar data), copies
   // [data,data+data_size) to the allocated buffer(s). If |data| is null, no
@@ -151,6 +167,7 @@
 
   // Contiguous block of channel data.
   scoped_ptr<uint8, base::AlignedFreeDeleter> data_;
+  size_t data_size_;
 
   // For planar data, points to each channels data.
   std::vector<uint8*> channel_data_;
diff --git a/media/base/sample_format.cc b/media/base/sample_format.cc
index 0c84f55..0ee7f5e 100644
--- a/media/base/sample_format.cc
+++ b/media/base/sample_format.cc
@@ -54,4 +54,42 @@
   return "";
 }
 
+bool IsPlanar(SampleFormat sample_format) {
+  switch (sample_format) {
+    case kSampleFormatPlanarS16:
+    case kSampleFormatPlanarF32:
+    case kSampleFormatPlanarS32:
+      return true;
+    case kUnknownSampleFormat:
+    case kSampleFormatU8:
+    case kSampleFormatS16:
+    case kSampleFormatS24:
+    case kSampleFormatS32:
+    case kSampleFormatF32:
+      return false;
+  }
+
+  NOTREACHED() << "Invalid sample format provided: " << sample_format;
+  return false;
+}
+
+bool IsInterleaved(SampleFormat sample_format) {
+  switch (sample_format) {
+    case kSampleFormatU8:
+    case kSampleFormatS16:
+    case kSampleFormatS24:
+    case kSampleFormatS32:
+    case kSampleFormatF32:
+      return true;
+    case kUnknownSampleFormat:
+    case kSampleFormatPlanarS16:
+    case kSampleFormatPlanarF32:
+    case kSampleFormatPlanarS32:
+      return false;
+  }
+
+  NOTREACHED() << "Invalid sample format provided: " << sample_format;
+  return false;
+}
+
 }  // namespace media
diff --git a/media/base/sample_format.h b/media/base/sample_format.h
index 12ebeb8..53d0cb9 100644
--- a/media/base/sample_format.h
+++ b/media/base/sample_format.h
@@ -35,6 +35,12 @@
 // Returns the name of the sample format as a string
 MEDIA_EXPORT const char* SampleFormatToString(SampleFormat sample_format);
 
+// Returns true if |sample_format| is planar, false otherwise.
+MEDIA_EXPORT bool IsPlanar(SampleFormat sample_format);
+
+// Returns true if |sample_format| is interleaved, false otherwise.
+MEDIA_EXPORT bool IsInterleaved(SampleFormat sample_format);
+
 }  // namespace media
 
 #endif  // MEDIA_BASE_SAMPLE_FORMAT_H
diff --git a/media/mojo/interfaces/decryptor.mojom b/media/mojo/interfaces/decryptor.mojom
index 9c5d678..e25df3e 100644
--- a/media/mojo/interfaces/decryptor.mojom
+++ b/media/mojo/interfaces/decryptor.mojom
@@ -7,10 +7,6 @@
 import "media/mojo/interfaces/demuxer_stream.mojom";
 import "media/mojo/interfaces/media_types.mojom";
 
-// TODO(xhwang): Add mojo types for AudioBuffer and VideoFrame.
-struct AudioBuffer {};
-struct VideoFrame {};
-
 // Interface for decrypting (and decoding) encrypted streams.
 // See media/base/decryptor.h for details.
 interface Decryptor {
diff --git a/media/mojo/interfaces/media_types.mojom b/media/mojo/interfaces/media_types.mojom
index 74f5383..befd80a 100644
--- a/media/mojo/interfaces/media_types.mojom
+++ b/media/mojo/interfaces/media_types.mojom
@@ -232,3 +232,58 @@
   // Indicates this buffer is part of a splice around |splice_timestamp_usec|.
   int64 splice_timestamp_usec;
 };
+
+// This defines a mojo transport format for media::AudioBuffer.
+struct AudioBuffer {
+  // Format of the audio.
+  SampleFormat sample_format;
+
+  // How the channels are laid out.
+  ChannelLayout channel_layout;
+
+  // Number of channels.
+  int32 channel_count;
+
+  // Sample rate of the buffer.
+  int32 sample_rate;
+
+  // Number of frames in the buffer.
+  int32 frame_count;
+
+  // True if end of stream.
+  bool end_of_stream;
+
+  // Timestamp in microseconds of the first frame.
+  int64 timestamp_usec;
+
+  // Channel data. Will be null for EOS buffers.
+  array<uint8>? data;
+};
+
+// This defines a mojo transport format for media::VideoFrame.
+// TODO(jrummell): Support shared memory based VideoFrame to avoid copying
+// the data multiple times.
+struct VideoFrame {
+  // Format of the frame.
+  VideoFormat format;
+
+  // Width and height of the video frame, in pixels.
+  mojo.Size coded_size;
+
+  // Visible size of the frame.
+  mojo.Rect visible_rect;
+
+  // Natural size of the frame.
+  mojo.Size natural_size;
+
+  // True if end of stream.
+  bool end_of_stream;
+
+  // Timestamp in microseconds of the associated frame.
+  int64 timestamp_usec;
+
+  // Frame data for each plane. Will be null for EOS buffers.
+  array<uint8>? y_data;
+  array<uint8>? u_data;
+  array<uint8>? v_data;
+};
diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn
index 24fcdfc..23690f80 100644
--- a/media/mojo/services/BUILD.gn
+++ b/media/mojo/services/BUILD.gn
@@ -183,8 +183,10 @@
     "//base",
     "//base/test:test_support",
     "//media",
+    "//media/base:test_support",
     "//media/mojo/interfaces",
     "//mojo/environment:chromium",
+    "//testing/gmock",
     "//testing/gtest",
     "//third_party/mojo/src/mojo/edk/system",
     "//third_party/mojo/src/mojo/edk/test:run_all_unittests",
diff --git a/media/mojo/services/media_type_converters.cc b/media/mojo/services/media_type_converters.cc
index 5f84a49a..fc733aa 100644
--- a/media/mojo/services/media_type_converters.cc
+++ b/media/mojo/services/media_type_converters.cc
@@ -4,6 +4,7 @@
 
 #include "media/mojo/services/media_type_converters.h"
 
+#include "media/base/audio_buffer.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/buffering_state.h"
 #include "media/base/cdm_config.h"
@@ -13,6 +14,7 @@
 #include "media/base/demuxer_stream.h"
 #include "media/base/media_keys.h"
 #include "media/base/video_decoder_config.h"
+#include "media/base/video_frame.h"
 #include "media/mojo/interfaces/demuxer_stream.mojom.h"
 #include "mojo/converters/geometry/geometry_type_converters.h"
 
@@ -529,4 +531,124 @@
   return config;
 }
 
+// static
+media::interfaces::AudioBufferPtr
+TypeConverter<media::interfaces::AudioBufferPtr,
+              scoped_refptr<media::AudioBuffer>>::
+    Convert(const scoped_refptr<media::AudioBuffer>& input) {
+  media::interfaces::AudioBufferPtr buffer(
+      media::interfaces::AudioBuffer::New());
+  buffer->sample_format =
+      static_cast<media::interfaces::SampleFormat>(input->sample_format_);
+  buffer->channel_layout =
+      static_cast<media::interfaces::ChannelLayout>(input->channel_layout());
+  buffer->channel_count = input->channel_count();
+  buffer->sample_rate = input->sample_rate();
+  buffer->frame_count = input->frame_count();
+  buffer->end_of_stream = input->end_of_stream();
+  buffer->timestamp_usec = input->timestamp().InMicroseconds();
+
+  if (!input->end_of_stream()) {
+    std::vector<uint8_t> input_data(input->data_.get(),
+                                    input->data_.get() + input->data_size_);
+    buffer->data.Swap(&input_data);
+  }
+
+  return buffer.Pass();
+}
+
+// static
+scoped_refptr<media::AudioBuffer>
+TypeConverter<scoped_refptr<media::AudioBuffer>,
+              media::interfaces::AudioBufferPtr>::
+    Convert(const media::interfaces::AudioBufferPtr& input) {
+  if (input->end_of_stream)
+    return media::AudioBuffer::CreateEOSBuffer();
+
+  // Setup channel pointers.  AudioBuffer::CopyFrom() will only use the first
+  // one in the case of interleaved data.
+  std::vector<const uint8_t*> channel_ptrs(input->channel_count, nullptr);
+  std::vector<uint8_t> storage = input->data.storage();
+  const size_t size_per_channel = storage.size() / input->channel_count;
+  DCHECK_EQ(0u, storage.size() % input->channel_count);
+  for (int i = 0; i < input->channel_count; ++i)
+    channel_ptrs[i] = storage.data() + i * size_per_channel;
+
+  return media::AudioBuffer::CopyFrom(
+      static_cast<media::SampleFormat>(input->sample_format),
+      static_cast<media::ChannelLayout>(input->channel_layout),
+      input->channel_count, input->sample_rate, input->frame_count,
+      &channel_ptrs[0],
+      base::TimeDelta::FromMicroseconds(input->timestamp_usec));
+}
+
+// static
+media::interfaces::VideoFramePtr
+TypeConverter<media::interfaces::VideoFramePtr,
+              scoped_refptr<media::VideoFrame>>::
+    Convert(const scoped_refptr<media::VideoFrame>& input) {
+  media::interfaces::VideoFramePtr buffer(media::interfaces::VideoFrame::New());
+  buffer->end_of_stream =
+      input->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM);
+  if (buffer->end_of_stream)
+    return buffer.Pass();
+
+  // handle non EOS buffer.
+  buffer->format = static_cast<media::interfaces::VideoFormat>(input->format());
+  buffer->coded_size = Size::From(input->coded_size());
+  buffer->visible_rect = Rect::From(input->visible_rect());
+  buffer->natural_size = Size::From(input->natural_size());
+  buffer->timestamp_usec = input->timestamp().InMicroseconds();
+
+  if (!input->coded_size().IsEmpty()) {
+    // TODO(jrummell): Use a shared buffer rather than copying the data for
+    // each plane.
+    std::vector<uint8_t> y_data(
+        input->data(media::VideoFrame::kYPlane),
+        input->data(media::VideoFrame::kYPlane) +
+            input->rows(media::VideoFrame::kYPlane) *
+                input->stride(media::VideoFrame::kYPlane));
+    buffer->y_data.Swap(&y_data);
+
+    std::vector<uint8_t> u_data(
+        input->data(media::VideoFrame::kUPlane),
+        input->data(media::VideoFrame::kUPlane) +
+            input->rows(media::VideoFrame::kUPlane) *
+                input->stride(media::VideoFrame::kUPlane));
+    buffer->u_data.Swap(&u_data);
+
+    std::vector<uint8_t> v_data(
+        input->data(media::VideoFrame::kVPlane),
+        input->data(media::VideoFrame::kVPlane) +
+            input->rows(media::VideoFrame::kVPlane) *
+                input->stride(media::VideoFrame::kVPlane));
+    buffer->v_data.Swap(&v_data);
+  }
+
+  return buffer.Pass();
+}
+
+// static
+scoped_refptr<media::VideoFrame>
+TypeConverter<scoped_refptr<media::VideoFrame>,
+              media::interfaces::VideoFramePtr>::
+    Convert(const media::interfaces::VideoFramePtr& input) {
+  if (input->end_of_stream)
+    return media::VideoFrame::CreateEOSFrame();
+
+  scoped_refptr<media::VideoFrame> frame = media::VideoFrame::CreateFrame(
+      static_cast<media::VideoPixelFormat>(input->format),
+      input->coded_size.To<gfx::Size>(), input->visible_rect.To<gfx::Rect>(),
+      input->natural_size.To<gfx::Size>(),
+      base::TimeDelta::FromMicroseconds(input->timestamp_usec));
+  memcpy(frame->data(media::VideoFrame::kYPlane),
+         input->y_data.storage().data(), input->y_data.storage().size());
+  memcpy(frame->data(media::VideoFrame::kUPlane),
+         input->u_data.storage().data(), input->u_data.storage().size());
+  memcpy(frame->data(media::VideoFrame::kVPlane),
+         input->v_data.storage().data(), input->v_data.storage().size());
+
+  return frame.Pass();
+}
+
 }  // namespace mojo
diff --git a/media/mojo/services/media_type_converters.h b/media/mojo/services/media_type_converters.h
index 0133a99..92450c8 100644
--- a/media/mojo/services/media_type_converters.h
+++ b/media/mojo/services/media_type_converters.h
@@ -12,10 +12,12 @@
 #include "mojo/public/cpp/bindings/type_converter.h"
 
 namespace media {
+class AudioBuffer;
 class AudioDecoderConfig;
 class DecoderBuffer;
 class DecryptConfig;
 class VideoDecoderConfig;
+class VideoFrame;
 struct CdmConfig;
 struct CdmKeyInformation;
 struct SubsampleEntry;
@@ -112,6 +114,32 @@
   static media::CdmConfig Convert(const media::interfaces::CdmConfigPtr& input);
 };
 
+template <>
+struct TypeConverter<media::interfaces::AudioBufferPtr,
+                     scoped_refptr<media::AudioBuffer>> {
+  static media::interfaces::AudioBufferPtr Convert(
+      const scoped_refptr<media::AudioBuffer>& input);
+};
+template <>
+struct TypeConverter<scoped_refptr<media::AudioBuffer>,
+                     media::interfaces::AudioBufferPtr> {
+  static scoped_refptr<media::AudioBuffer> Convert(
+      const media::interfaces::AudioBufferPtr& input);
+};
+
+template <>
+struct TypeConverter<media::interfaces::VideoFramePtr,
+                     scoped_refptr<media::VideoFrame>> {
+  static media::interfaces::VideoFramePtr Convert(
+      const scoped_refptr<media::VideoFrame>& input);
+};
+template <>
+struct TypeConverter<scoped_refptr<media::VideoFrame>,
+                     media::interfaces::VideoFramePtr> {
+  static scoped_refptr<media::VideoFrame> Convert(
+      const media::interfaces::VideoFramePtr& input);
+};
+
 }  // namespace mojo
 
 #endif  // MEDIA_MOJO_SERVICES_MEDIA_TYPE_CONVERTERS_H_
diff --git a/media/mojo/services/media_type_converters_unittest.cc b/media/mojo/services/media_type_converters_unittest.cc
index 38559f3..dae82d4c 100644
--- a/media/mojo/services/media_type_converters_unittest.cc
+++ b/media/mojo/services/media_type_converters_unittest.cc
@@ -4,14 +4,87 @@
 
 #include "media/mojo/services/media_type_converters.h"
 
+#include <string.h>
+
+#include "media/base/audio_buffer.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/cdm_config.h"
 #include "media/base/decoder_buffer.h"
 #include "media/base/media_util.h"
+#include "media/base/sample_format.h"
+#include "media/base/test_helpers.h"
+#include "media/base/video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace media {
 
+namespace {
+
+void CompareBytes(uint8* original_data, uint8* result_data, size_t length) {
+  EXPECT_GT(length, 0u);
+  EXPECT_EQ(memcmp(original_data, result_data, length), 0);
+}
+
+void CompareAudioBuffers(SampleFormat sample_format,
+                         const scoped_refptr<AudioBuffer>& original,
+                         const scoped_refptr<AudioBuffer>& result) {
+  EXPECT_EQ(original->frame_count(), result->frame_count());
+  EXPECT_EQ(original->timestamp(), result->timestamp());
+  EXPECT_EQ(original->duration(), result->duration());
+  EXPECT_EQ(original->sample_rate(), result->sample_rate());
+  EXPECT_EQ(original->channel_count(), result->channel_count());
+  EXPECT_EQ(original->channel_layout(), result->channel_layout());
+  EXPECT_EQ(original->end_of_stream(), result->end_of_stream());
+
+  // Compare bytes in buffer.
+  int bytes_per_channel =
+      original->frame_count() * SampleFormatToBytesPerChannel(sample_format);
+  if (IsPlanar(sample_format)) {
+    for (int i = 0; i < original->channel_count(); ++i) {
+      CompareBytes(original->channel_data()[i], result->channel_data()[i],
+                   bytes_per_channel);
+    }
+    return;
+  }
+
+  DCHECK(IsInterleaved(sample_format)) << sample_format;
+  CompareBytes(original->channel_data()[0], result->channel_data()[0],
+               bytes_per_channel * original->channel_count());
+}
+
+void CompareVideoPlane(size_t plane,
+                       const scoped_refptr<VideoFrame>& original,
+                       const scoped_refptr<VideoFrame>& result) {
+  EXPECT_EQ(original->stride(plane), result->stride(plane));
+  EXPECT_EQ(original->row_bytes(plane), result->row_bytes(plane));
+  EXPECT_EQ(original->rows(plane), result->rows(plane));
+  CompareBytes(original->data(plane), result->data(plane),
+               original->rows(plane) * original->row_bytes(plane));
+}
+
+void CompareVideoFrames(const scoped_refptr<VideoFrame>& original,
+                        const scoped_refptr<VideoFrame>& result) {
+  if (original->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM)) {
+    EXPECT_TRUE(
+        result->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM));
+    return;
+  }
+
+  EXPECT_EQ(original->format(), result->format());
+  EXPECT_EQ(original->coded_size().height(), result->coded_size().height());
+  EXPECT_EQ(original->coded_size().width(), result->coded_size().width());
+  EXPECT_EQ(original->visible_rect().height(), result->visible_rect().height());
+  EXPECT_EQ(original->visible_rect().width(), result->visible_rect().width());
+  EXPECT_EQ(original->natural_size().height(), result->natural_size().height());
+  EXPECT_EQ(original->natural_size().width(), result->natural_size().width());
+
+  CompareVideoPlane(media::VideoFrame::kYPlane, original, result);
+  CompareVideoPlane(media::VideoFrame::kUPlane, original, result);
+  CompareVideoPlane(media::VideoFrame::kVPlane, original, result);
+}
+
+}  // namespace
+
 TEST(MediaTypeConvertersTest, ConvertDecoderBuffer_Normal) {
   const uint8 kData[] = "hello, world";
   const uint8 kSideData[] = "sideshow bob";
@@ -172,4 +245,88 @@
   EXPECT_EQ(config.use_hw_secure_codecs, result.use_hw_secure_codecs);
 }
 
+TEST(MediaTypeConvertersTest, ConvertAudioBuffer_EOS) {
+  // Original.
+  scoped_refptr<AudioBuffer> buffer(AudioBuffer::CreateEOSBuffer());
+
+  // Convert to and back.
+  interfaces::AudioBufferPtr ptr(interfaces::AudioBuffer::From(buffer));
+  scoped_refptr<AudioBuffer> result(ptr.To<scoped_refptr<AudioBuffer>>());
+
+  // Compare.
+  EXPECT_TRUE(result->end_of_stream());
+}
+
+TEST(MediaTypeConvertersTest, ConvertAudioBuffer_MONO) {
+  // Original.
+  const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_MONO;
+  const int kSampleRate = 48000;
+  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<uint8>(
+      kSampleFormatU8, kChannelLayout,
+      ChannelLayoutToChannelCount(kChannelLayout), kSampleRate, 1, 1,
+      kSampleRate / 100, base::TimeDelta());
+
+  // Convert to and back.
+  interfaces::AudioBufferPtr ptr(interfaces::AudioBuffer::From(buffer));
+  scoped_refptr<AudioBuffer> result(ptr.To<scoped_refptr<AudioBuffer>>());
+
+  // Compare.
+  CompareAudioBuffers(kSampleFormatU8, buffer, result);
+}
+
+TEST(MediaTypeConvertersTest, ConvertAudioBuffer_FLOAT) {
+  // Original.
+  const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_4_0;
+  const int kSampleRate = 48000;
+  const base::TimeDelta start_time = base::TimeDelta::FromSecondsD(1000.0);
+  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<float>(
+      kSampleFormatPlanarF32, kChannelLayout,
+      ChannelLayoutToChannelCount(kChannelLayout), kSampleRate, 0.0f, 1.0f,
+      kSampleRate / 10, start_time);
+  // Convert to and back.
+  interfaces::AudioBufferPtr ptr(interfaces::AudioBuffer::From(buffer));
+  scoped_refptr<AudioBuffer> result(ptr.To<scoped_refptr<AudioBuffer>>());
+
+  // Compare.
+  CompareAudioBuffers(kSampleFormatPlanarF32, buffer, result);
+}
+
+TEST(MediaTypeConvertersTest, ConvertVideoFrame_EOS) {
+  // Original.
+  scoped_refptr<VideoFrame> buffer(VideoFrame::CreateEOSFrame());
+
+  // Convert to and back.
+  interfaces::VideoFramePtr ptr(interfaces::VideoFrame::From(buffer));
+  scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
+
+  // Compare.
+  CompareVideoFrames(buffer, result);
+}
+
+TEST(MediaTypeConvertersTest, ConvertVideoFrame_BlackFrame) {
+  // Original.
+  scoped_refptr<VideoFrame> buffer(
+      VideoFrame::CreateBlackFrame(gfx::Size(100, 100)));
+
+  // Convert to and back.
+  interfaces::VideoFramePtr ptr(interfaces::VideoFrame::From(buffer));
+  scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
+
+  // Compare.
+  CompareVideoFrames(buffer, result);
+}
+
+TEST(MediaTypeConvertersTest, ConvertVideoFrame_ColorFrame) {
+  // Original.
+  scoped_refptr<VideoFrame> buffer(VideoFrame::CreateColorFrame(
+      gfx::Size(50, 100), 255, 128, 128, base::TimeDelta::FromSeconds(26)));
+
+  // Convert to and back.
+  interfaces::VideoFramePtr ptr(interfaces::VideoFrame::From(buffer));
+  scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
+
+  // Compare.
+  CompareVideoFrames(buffer, result);
+}
+
 }  // namespace media
diff --git a/mojo/services/network/url_loader_impl.cc b/mojo/services/network/url_loader_impl.cc
index 002f2ee4..dfb1566 100644
--- a/mojo/services/network/url_loader_impl.cc
+++ b/mojo/services/network/url_loader_impl.cc
@@ -4,7 +4,9 @@
 
 #include "mojo/services/network/url_loader_impl.h"
 
-#include "base/memory/scoped_vector.h"
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "mojo/common/common_type_converters.h"
 #include "mojo/common/url_type_converters.h"
@@ -190,13 +192,13 @@
     url_request_->SetExtraRequestHeaders(headers);
   }
   if (request->body) {
-    ScopedVector<net::UploadElementReader> element_readers;
+    std::vector<scoped_ptr<net::UploadElementReader>> element_readers;
     for (size_t i = 0; i < request->body.size(); ++i) {
-      element_readers.push_back(
-          new UploadDataPipeElementReader(request->body[i].Pass()));
+      element_readers.push_back(make_scoped_ptr(
+          new UploadDataPipeElementReader(request->body[i].Pass())));
     }
     url_request_->set_upload(make_scoped_ptr<net::UploadDataStream>(
-        new net::ElementsUploadDataStream(element_readers.Pass(), 0)));
+        new net::ElementsUploadDataStream(std::move(element_readers), 0)));
   }
   if (request->bypass_cache)
     url_request_->SetLoadFlags(net::LOAD_BYPASS_CACHE);
diff --git a/net/base/elements_upload_data_stream.cc b/net/base/elements_upload_data_stream.cc
index e23f632a..29b77ba 100644
--- a/net/base/elements_upload_data_stream.cc
+++ b/net/base/elements_upload_data_stream.cc
@@ -15,14 +15,13 @@
 namespace net {
 
 ElementsUploadDataStream::ElementsUploadDataStream(
-    ScopedVector<UploadElementReader> element_readers,
+    std::vector<scoped_ptr<UploadElementReader>> element_readers,
     int64_t identifier)
     : UploadDataStream(false, identifier),
-      element_readers_(element_readers.Pass()),
+      element_readers_(std::move(element_readers)),
       element_index_(0),
       read_failed_(false),
-      weak_ptr_factory_(this) {
-}
+      weak_ptr_factory_(this) {}
 
 ElementsUploadDataStream::~ElementsUploadDataStream() {
 }
@@ -30,10 +29,10 @@
 scoped_ptr<UploadDataStream> ElementsUploadDataStream::CreateWithReader(
     scoped_ptr<UploadElementReader> reader,
     int64_t identifier) {
-  ScopedVector<UploadElementReader> readers;
-  readers.push_back(reader.Pass());
+  std::vector<scoped_ptr<UploadElementReader>> readers;
+  readers.push_back(std::move(reader));
   return scoped_ptr<UploadDataStream>(
-      new ElementsUploadDataStream(readers.Pass(), identifier));
+      new ElementsUploadDataStream(std::move(readers), identifier));
 }
 
 int ElementsUploadDataStream::InitInternal() {
@@ -48,14 +47,14 @@
 }
 
 bool ElementsUploadDataStream::IsInMemory() const {
-  for (size_t i = 0; i < element_readers_.size(); ++i) {
-    if (!element_readers_[i]->IsInMemory())
+  for (const scoped_ptr<UploadElementReader>& it : element_readers_) {
+    if (!it->IsInMemory())
       return false;
   }
   return true;
 }
 
-const ScopedVector<UploadElementReader>*
+const std::vector<scoped_ptr<UploadElementReader>>*
 ElementsUploadDataStream::GetElementReaders() const {
   return &element_readers_;
 }
@@ -69,7 +68,7 @@
 int ElementsUploadDataStream::InitElements(size_t start_index) {
   // Call Init() for all elements.
   for (size_t i = start_index; i < element_readers_.size(); ++i) {
-    UploadElementReader* reader = element_readers_[i];
+    UploadElementReader* reader = element_readers_[i].get();
     // When new_result is ERR_IO_PENDING, InitInternal() will be called
     // with start_index == i + 1 when reader->Init() finishes.
     int result = reader->Init(
@@ -83,8 +82,8 @@
   }
 
   uint64_t total_size = 0;
-  for (size_t i = 0; i < element_readers_.size(); ++i) {
-    total_size += element_readers_[i]->GetContentLength();
+  for (const scoped_ptr<UploadElementReader>& it : element_readers_) {
+    total_size += it->GetContentLength();
   }
   SetSize(total_size);
   return OK;
@@ -105,7 +104,7 @@
 int ElementsUploadDataStream::ReadElements(
     const scoped_refptr<DrainableIOBuffer>& buf) {
   while (!read_failed_ && element_index_ < element_readers_.size()) {
-    UploadElementReader* reader = element_readers_[element_index_];
+    UploadElementReader* reader = element_readers_[element_index_].get();
 
     if (reader->BytesRemaining() == 0) {
       ++element_index_;
diff --git a/net/base/elements_upload_data_stream.h b/net/base/elements_upload_data_stream.h
index c65c3c61..e4773298 100644
--- a/net/base/elements_upload_data_stream.h
+++ b/net/base/elements_upload_data_stream.h
@@ -5,11 +5,12 @@
 #ifndef NET_BASE_ELEMENTS_UPLOAD_DATA_STREAM_H_
 #define NET_BASE_ELEMENTS_UPLOAD_DATA_STREAM_H_
 
+#include <vector>
+
 #include "base/basictypes.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "base/memory/weak_ptr.h"
 #include "net/base/net_export.h"
 #include "net/base/upload_data_stream.h"
@@ -23,8 +24,9 @@
 // A non-chunked UploadDataStream consisting of one or more UploadElements.
 class NET_EXPORT ElementsUploadDataStream : public UploadDataStream {
  public:
-  ElementsUploadDataStream(ScopedVector<UploadElementReader> element_readers,
-                           int64_t identifier);
+  ElementsUploadDataStream(
+      std::vector<scoped_ptr<UploadElementReader>> element_readers,
+      int64_t identifier);
 
   ~ElementsUploadDataStream() override;
 
@@ -37,7 +39,8 @@
  private:
   // UploadDataStream implementation.
   bool IsInMemory() const override;
-  const ScopedVector<UploadElementReader>* GetElementReaders() const override;
+  const std::vector<scoped_ptr<UploadElementReader>>* GetElementReaders()
+      const override;
   int InitInternal() override;
   int ReadInternal(IOBuffer* buf, int buf_len) override;
   void ResetInternal() override;
@@ -65,7 +68,7 @@
   void ProcessReadResult(const scoped_refptr<DrainableIOBuffer>& buf,
                          int result);
 
-  ScopedVector<UploadElementReader> element_readers_;
+  std::vector<scoped_ptr<UploadElementReader>> element_readers_;
 
   // Index of the current upload element (i.e. the element currently being
   // read). The index is used as a cursor to iterate over elements in
diff --git a/net/base/elements_upload_data_stream_unittest.cc b/net/base/elements_upload_data_stream_unittest.cc
index 8c72054..a395c83 100644
--- a/net/base/elements_upload_data_stream_unittest.cc
+++ b/net/base/elements_upload_data_stream_unittest.cc
@@ -142,12 +142,12 @@
                          bool error_expected);
 
   base::ScopedTempDir temp_dir_;
-  ScopedVector<UploadElementReader> element_readers_;
+  std::vector<scoped_ptr<UploadElementReader>> element_readers_;
 };
 
 TEST_F(ElementsUploadDataStreamTest, EmptyUploadData) {
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
   ASSERT_EQ(OK, stream->Init(CompletionCallback()));
   EXPECT_TRUE(stream->IsInMemory());
   EXPECT_EQ(0U, stream->size());
@@ -156,10 +156,10 @@
 }
 
 TEST_F(ElementsUploadDataStreamTest, ConsumeAllBytes) {
-  element_readers_.push_back(new UploadBytesElementReader(
-      kTestData, kTestDataSize));
+  element_readers_.push_back(
+      make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
   ASSERT_EQ(OK, stream->Init(CompletionCallback()));
   EXPECT_TRUE(stream->IsInMemory());
   EXPECT_EQ(kTestDataSize, stream->size());
@@ -182,13 +182,13 @@
   ASSERT_EQ(static_cast<int>(kTestDataSize),
             base::WriteFile(temp_file_path, kTestData, kTestDataSize));
 
-  element_readers_.push_back(
-      new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                  temp_file_path, 0, kuint64max, base::Time()));
+  element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+      base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0, kuint64max,
+      base::Time())));
 
   TestCompletionCallback init_callback;
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
   ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
   ASSERT_EQ(OK, init_callback.WaitForResult());
   EXPECT_FALSE(stream->IsInMemory());
@@ -218,13 +218,13 @@
   UploadFileElementReader::ScopedOverridingContentLengthForTests
       overriding_content_length(kFakeSize);
 
-  element_readers_.push_back(
-      new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                  temp_file_path, 0, kuint64max, base::Time()));
+  element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+      base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0, kuint64max,
+      base::Time())));
 
   TestCompletionCallback init_callback;
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
   ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
   ASSERT_EQ(OK, init_callback.WaitForResult());
   EXPECT_FALSE(stream->IsInMemory());
@@ -251,18 +251,18 @@
 
 TEST_F(ElementsUploadDataStreamTest, ReadErrorSync) {
   // This element cannot be read.
-  MockUploadElementReader* reader =
-      new MockUploadElementReader(kTestDataSize, true);
+  scoped_ptr<MockUploadElementReader> reader(
+      new MockUploadElementReader(kTestDataSize, true));
   EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
   reader->SetReadExpectation(ERR_FAILED);
-  element_readers_.push_back(reader);
+  element_readers_.push_back(std::move(reader));
 
   // This element is ignored because of the error from the previous reader.
-  element_readers_.push_back(new UploadBytesElementReader(
-      kTestData, kTestDataSize));
+  element_readers_.push_back(
+      make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
 
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   // Run Init().
   ASSERT_EQ(OK, stream->Init(CompletionCallback()));
@@ -287,18 +287,18 @@
 
 TEST_F(ElementsUploadDataStreamTest, ReadErrorAsync) {
   // This element cannot be read.
-  MockUploadElementReader* reader =
-      new MockUploadElementReader(kTestDataSize, false);
+  scoped_ptr<MockUploadElementReader> reader(
+      new MockUploadElementReader(kTestDataSize, false));
   reader->SetAsyncInitExpectation(OK);
   reader->SetReadExpectation(ERR_FAILED);
-  element_readers_.push_back(reader);
+  element_readers_.push_back(std::move(reader));
 
   // This element is ignored because of the error from the previous reader.
-  element_readers_.push_back(new UploadBytesElementReader(
-      kTestData, kTestDataSize));
+  element_readers_.push_back(
+      make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
 
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   // Run Init().
   TestCompletionCallback init_callback;
@@ -334,17 +334,17 @@
 
   const uint64_t kFileRangeOffset = 1;
   const uint64_t kFileRangeLength = 4;
-  element_readers_.push_back(new UploadFileElementReader(
+  element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
       base::ThreadTaskRunnerHandle::Get().get(), temp_file_path,
-      kFileRangeOffset, kFileRangeLength, base::Time()));
+      kFileRangeOffset, kFileRangeLength, base::Time())));
 
-  element_readers_.push_back(new UploadBytesElementReader(
-      kTestData, kTestDataSize));
+  element_readers_.push_back(
+      make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
 
   const uint64_t kStreamSize = kTestDataSize + kFileRangeLength;
   TestCompletionCallback init_callback;
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
   ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
   ASSERT_EQ(OK, init_callback.WaitForResult());
   EXPECT_FALSE(stream->IsInMemory());
@@ -367,30 +367,33 @@
 // Init() with on-memory and not-on-memory readers.
 TEST_F(ElementsUploadDataStreamTest, InitAsync) {
   // Create UploadDataStream with mock readers.
-  MockUploadElementReader* reader = NULL;
-
-  reader = new MockUploadElementReader(kTestDataSize, true);
+  scoped_ptr<MockUploadElementReader> reader(
+      new MockUploadElementReader(kTestDataSize, true));
   EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
-  element_readers_.push_back(reader);
+  element_readers_.push_back(std::move(reader));
 
-  reader = new MockUploadElementReader(kTestDataSize, true);
-  EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
-  element_readers_.push_back(reader);
+  scoped_ptr<MockUploadElementReader> reader2(
+      new MockUploadElementReader(kTestDataSize, true));
+  EXPECT_CALL(*reader2, Init(_)).WillOnce(Return(OK));
+  element_readers_.push_back(std::move(reader2));
 
-  reader = new MockUploadElementReader(kTestDataSize, false);
-  reader->SetAsyncInitExpectation(OK);
-  element_readers_.push_back(reader);
+  scoped_ptr<MockUploadElementReader> reader3(
+      new MockUploadElementReader(kTestDataSize, false));
+  reader3->SetAsyncInitExpectation(OK);
+  element_readers_.push_back(std::move(reader3));
 
-  reader = new MockUploadElementReader(kTestDataSize, false);
-  reader->SetAsyncInitExpectation(OK);
-  element_readers_.push_back(reader);
+  scoped_ptr<MockUploadElementReader> reader4(
+      new MockUploadElementReader(kTestDataSize, false));
+  reader4->SetAsyncInitExpectation(OK);
+  element_readers_.push_back(std::move(reader4));
 
-  reader = new MockUploadElementReader(kTestDataSize, true);
-  EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
-  element_readers_.push_back(reader);
+  scoped_ptr<MockUploadElementReader> reader5(
+      new MockUploadElementReader(kTestDataSize, true));
+  EXPECT_CALL(*reader5, Init(_)).WillOnce(Return(OK));
+  element_readers_.push_back(std::move(reader5));
 
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   // Run Init().
   TestCompletionCallback callback;
@@ -401,14 +404,13 @@
 // Init() of a reader fails asynchronously.
 TEST_F(ElementsUploadDataStreamTest, InitAsyncFailureAsync) {
   // Create UploadDataStream with a mock reader.
-  MockUploadElementReader* reader = NULL;
-
-  reader = new MockUploadElementReader(kTestDataSize, false);
+  scoped_ptr<MockUploadElementReader> reader(
+      new MockUploadElementReader(kTestDataSize, false));
   reader->SetAsyncInitExpectation(ERR_FAILED);
-  element_readers_.push_back(reader);
+  element_readers_.push_back(std::move(reader));
 
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   // Run Init().
   TestCompletionCallback callback;
@@ -419,18 +421,18 @@
 // Init() of a reader fails synchronously.
 TEST_F(ElementsUploadDataStreamTest, InitAsyncFailureSync) {
   // Create UploadDataStream with mock readers.
-  MockUploadElementReader* reader = NULL;
-
-  reader = new MockUploadElementReader(kTestDataSize, false);
+  scoped_ptr<MockUploadElementReader> reader(
+      new MockUploadElementReader(kTestDataSize, false));
   reader->SetAsyncInitExpectation(OK);
-  element_readers_.push_back(reader);
+  element_readers_.push_back(std::move(reader));
 
-  reader = new MockUploadElementReader(kTestDataSize, true);
-  EXPECT_CALL(*reader, Init(_)).WillOnce(Return(ERR_FAILED));
-  element_readers_.push_back(reader);
+  scoped_ptr<MockUploadElementReader> reader2(
+      new MockUploadElementReader(kTestDataSize, true));
+  EXPECT_CALL(*reader2, Init(_)).WillOnce(Return(ERR_FAILED));
+  element_readers_.push_back(std::move(reader2));
 
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   // Run Init().
   TestCompletionCallback callback;
@@ -440,10 +442,10 @@
 
 // Read with a buffer whose size is same as the data.
 TEST_F(ElementsUploadDataStreamTest, ReadAsyncWithExactSizeBuffer) {
-  element_readers_.push_back(new UploadBytesElementReader(
-      kTestData, kTestDataSize));
+  element_readers_.push_back(
+      make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   ASSERT_EQ(OK, stream->Init(CompletionCallback()));
   EXPECT_TRUE(stream->IsInMemory());
@@ -460,30 +462,32 @@
 // Async Read() with on-memory and not-on-memory readers.
 TEST_F(ElementsUploadDataStreamTest, ReadAsync) {
   // Create UploadDataStream with mock readers.
-  MockUploadElementReader* reader = NULL;
-
-  reader = new MockUploadElementReader(kTestDataSize, true);
+  scoped_ptr<MockUploadElementReader> reader(
+      new MockUploadElementReader(kTestDataSize, true));
   EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
   reader->SetReadExpectation(kTestDataSize);
-  element_readers_.push_back(reader);
+  element_readers_.push_back(std::move(reader));
 
-  reader = new MockUploadElementReader(kTestDataSize, false);
-  reader->SetAsyncInitExpectation(OK);
-  reader->SetReadExpectation(kTestDataSize);
-  element_readers_.push_back(reader);
+  scoped_ptr<MockUploadElementReader> reader2(
+      new MockUploadElementReader(kTestDataSize, false));
+  reader2->SetAsyncInitExpectation(OK);
+  reader2->SetReadExpectation(kTestDataSize);
+  element_readers_.push_back(std::move(reader2));
 
-  reader = new MockUploadElementReader(kTestDataSize, true);
-  EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
-  reader->SetReadExpectation(kTestDataSize);
-  element_readers_.push_back(reader);
+  scoped_ptr<MockUploadElementReader> reader3(
+      new MockUploadElementReader(kTestDataSize, true));
+  EXPECT_CALL(*reader3, Init(_)).WillOnce(Return(OK));
+  reader3->SetReadExpectation(kTestDataSize);
+  element_readers_.push_back(std::move(reader3));
 
-  reader = new MockUploadElementReader(kTestDataSize, false);
-  reader->SetAsyncInitExpectation(OK);
-  reader->SetReadExpectation(kTestDataSize);
-  element_readers_.push_back(reader);
+  scoped_ptr<MockUploadElementReader> reader4(
+      new MockUploadElementReader(kTestDataSize, false));
+  reader4->SetAsyncInitExpectation(OK);
+  reader4->SetReadExpectation(kTestDataSize);
+  element_readers_.push_back(std::move(reader4));
 
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   // Run Init().
   TestCompletionCallback init_callback;
@@ -520,13 +524,13 @@
     bool error_expected) {
   // Don't use element_readers_ here, as this function is called twice, and
   // reusing element_readers_ is wrong.
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadFileElementReader(
-      base::ThreadTaskRunnerHandle::Get().get(), file_path, 1, 2, time));
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
+      base::ThreadTaskRunnerHandle::Get().get(), file_path, 1, 2, time)));
 
   TestCompletionCallback init_callback;
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers), 0));
   ASSERT_EQ(ERR_IO_PENDING, stream->Init(init_callback.callback()));
   int error_code = init_callback.WaitForResult();
   if (error_expected)
@@ -562,13 +566,13 @@
             base::WriteFile(temp_file_path, kTestData, kTestDataSize));
 
   // Prepare data.
-  element_readers_.push_back(new UploadBytesElementReader(
-      kTestData, kTestDataSize));
   element_readers_.push_back(
-      new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                  temp_file_path, 0, kuint64max, base::Time()));
+      make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
+  element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+      base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0, kuint64max,
+      base::Time())));
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   std::string expected_data(kTestData, kTestData + kTestDataSize);
   expected_data += expected_data;
@@ -605,13 +609,13 @@
   TestCompletionCallback test_callback;
 
   // Prepare data.
-  element_readers_.push_back(new UploadBytesElementReader(
-      kTestData, kTestDataSize));
   element_readers_.push_back(
-      new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                  temp_file_path, 0, kuint64max, base::Time()));
+      make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
+  element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+      base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0, kuint64max,
+      base::Time())));
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   std::string expected_data(kTestData, kTestData + kTestDataSize);
   expected_data += expected_data;
@@ -645,13 +649,13 @@
             base::WriteFile(temp_file_path, kTestData, kTestDataSize));
 
   // Prepare data.
-  element_readers_.push_back(new UploadBytesElementReader(
-      kTestData, kTestDataSize));
   element_readers_.push_back(
-      new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                  temp_file_path, 0, kuint64max, base::Time()));
+      make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
+  element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+      base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0, kuint64max,
+      base::Time())));
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
   expected_data.insert(expected_data.end(), kTestData,
@@ -701,13 +705,13 @@
             base::WriteFile(temp_file_path, kTestData, kTestDataSize));
 
   // Prepare data.
-  element_readers_.push_back(new UploadBytesElementReader(
-      kTestData, kTestDataSize));
   element_readers_.push_back(
-      new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                  temp_file_path, 0, kuint64max, base::Time()));
+      make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
+  element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+      base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0, kuint64max,
+      base::Time())));
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
   expected_data.insert(expected_data.end(), kTestData,
@@ -747,13 +751,13 @@
             base::WriteFile(temp_file_path, kTestData, kTestDataSize));
 
   // Prepare data.
-  element_readers_.push_back(new UploadBytesElementReader(
-      kTestData, kTestDataSize));
   element_readers_.push_back(
-      new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                  temp_file_path, 0, kuint64max, base::Time()));
+      make_scoped_ptr(new UploadBytesElementReader(kTestData, kTestDataSize)));
+  element_readers_.push_back(make_scoped_ptr(new UploadFileElementReader(
+      base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0, kuint64max,
+      base::Time())));
   scoped_ptr<UploadDataStream> stream(
-      new ElementsUploadDataStream(element_readers_.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers_), 0));
 
   std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
   expected_data.insert(expected_data.end(), kTestData,
diff --git a/net/base/upload_data_stream.cc b/net/base/upload_data_stream.cc
index c2d88f9..23c760ea 100644
--- a/net/base/upload_data_stream.cc
+++ b/net/base/upload_data_stream.cc
@@ -88,7 +88,7 @@
   return false;
 }
 
-const ScopedVector<UploadElementReader>*
+const std::vector<scoped_ptr<UploadElementReader>>*
 UploadDataStream::GetElementReaders() const {
   return NULL;
 }
diff --git a/net/base/upload_data_stream.h b/net/base/upload_data_stream.h
index a4573ea..ebb20af 100644
--- a/net/base/upload_data_stream.h
+++ b/net/base/upload_data_stream.h
@@ -5,9 +5,11 @@
 #ifndef NET_BASE_UPLOAD_DATA_STREAM_H_
 #define NET_BASE_UPLOAD_DATA_STREAM_H_
 
+#include <vector>
+
 #include "base/basictypes.h"
 #include "base/macros.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
 #include "net/base/completion_callback.h"
 #include "net/base/net_export.h"
 
@@ -86,8 +88,8 @@
   virtual bool IsInMemory() const;
 
   // Returns a list of element readers owned by |this|, if it has any.
-  virtual const ScopedVector<UploadElementReader>*
-      GetElementReaders() const;
+  virtual const std::vector<scoped_ptr<UploadElementReader>>*
+  GetElementReaders() const;
 
  protected:
   // Must be called by subclasses when InitInternal and ReadInternal complete
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index 84dec61..76deac3f 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -7,10 +7,11 @@
 #include <stdint.h>
 
 #include <algorithm>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/string_util.h"
@@ -1414,12 +1415,12 @@
   MockHttpRequest writer_request(kSimpleGET_Transaction);
   writer_request.load_flags = LOAD_BYPASS_CACHE;
 
-  ScopedVector<Context> context_list;
+  std::vector<scoped_ptr<Context>> context_list;
   const int kNumTransactions = 4;
 
   for (int i = 0; i < kNumTransactions; ++i) {
-    context_list.push_back(new Context());
-    Context* c = context_list[i];
+    context_list.push_back(make_scoped_ptr(new Context()));
+    Context* c = context_list[i].get();
 
     c->result = cache.CreateTransaction(&c->trans);
     ASSERT_EQ(OK, c->result);
@@ -1438,13 +1439,12 @@
   EXPECT_EQ(2, cache.network_layer()->transaction_count());
 
   // Cancel the first queued transaction.
-  delete context_list[1];
-  context_list.get()[1] = NULL;
+  context_list[1].reset();
 
   for (int i = 0; i < kNumTransactions; ++i) {
     if (i == 1)
       continue;
-    Context* c = context_list[i];
+    Context* c = context_list[i].get();
     ASSERT_EQ(ERR_IO_PENDING, c->result);
     c->result = c->callback.WaitForResult();
     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
@@ -2926,9 +2926,10 @@
 
   const int64 kUploadId = 1;  // Just a dummy value.
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers),
                                               kUploadId);
   MockHttpRequest request(transaction);
   request.upload_data_stream = &upload_data_stream;
@@ -2958,9 +2959,10 @@
 
   const int64 kUploadId = 1;  // Just a dummy value.
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(),
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers),
                                               kUploadId);
 
   MockHttpRequest request(transaction);
@@ -2978,9 +2980,10 @@
 TEST(HttpCache, SimplePOST_SeparateCache) {
   MockHttpCache cache;
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
 
   MockTransaction transaction(kSimplePOST_Transaction);
   MockHttpRequest req1(transaction);
@@ -3017,9 +3020,10 @@
   EXPECT_EQ(0, cache.disk_cache()->open_count());
   EXPECT_EQ(1, cache.disk_cache()->create_count());
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
 
   transaction.method = "POST";
   transaction.status = "HTTP/1.1 205 No Content";
@@ -3056,9 +3060,10 @@
   EXPECT_EQ(0, cache.disk_cache()->open_count());
   EXPECT_EQ(1, cache.disk_cache()->create_count());
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   transaction.method = "POST";
   transaction.status = "HTTP/1.1 205 No Content";
@@ -3088,9 +3093,10 @@
   factory->FinishCreation();
   MockHttpCache cache(factory.Pass());
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   MockTransaction transaction(kSimplePOST_Transaction);
   AddMockTransaction(&transaction);
@@ -3117,9 +3123,10 @@
   EXPECT_EQ(0, cache.disk_cache()->open_count());
   EXPECT_EQ(1, cache.disk_cache()->create_count());
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 1);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
 
   transaction.method = "POST";
   transaction.status = "HTTP/1.1 100 Continue";
@@ -3428,9 +3435,10 @@
   MockTransaction transaction(kSimplePOST_Transaction);
   transaction.method = "PUT";
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   MockHttpRequest request(transaction);
   request.upload_data_stream = &upload_data_stream;
@@ -3457,9 +3465,10 @@
   EXPECT_EQ(0, cache.disk_cache()->open_count());
   EXPECT_EQ(1, cache.disk_cache()->create_count());
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   transaction.method = "PUT";
   MockHttpRequest req2(transaction);
@@ -3493,9 +3502,10 @@
   EXPECT_EQ(0, cache.disk_cache()->open_count());
   EXPECT_EQ(1, cache.disk_cache()->create_count());
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   transaction.method = "PUT";
   transaction.status = "HTTP/1.1 305 Use Proxy";
@@ -3531,9 +3541,10 @@
   EXPECT_EQ(0, cache.disk_cache()->open_count());
   EXPECT_EQ(1, cache.disk_cache()->create_count());
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   transaction.method = "PUT";
   transaction.status = "HTTP/1.1 404 Not Found";
@@ -3561,9 +3572,10 @@
   MockTransaction transaction(kSimplePOST_Transaction);
   transaction.method = "DELETE";
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   MockHttpRequest request(transaction);
   request.upload_data_stream = &upload_data_stream;
@@ -3590,9 +3602,10 @@
   EXPECT_EQ(0, cache.disk_cache()->open_count());
   EXPECT_EQ(1, cache.disk_cache()->create_count());
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello", 5));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello", 5)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   transaction.method = "DELETE";
   MockHttpRequest req2(transaction);
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 5c58bb606..f310d575 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -1180,9 +1180,10 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, Ignores100) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -6012,9 +6013,10 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request[2];
   // Transaction 1: a GET request that succeeds.  The socket is recycled
@@ -9107,11 +9109,11 @@
   UploadFileElementReader::ScopedOverridingContentLengthForTests
       overriding_content_length(kFakeSize);
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(
-      new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                  temp_file_path, 0, kuint64max, base::Time()));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
+      base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0, kuint64max,
+      base::Time())));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -9161,11 +9163,11 @@
                                    temp_file_content.length()));
   ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(make_scoped_ptr(
       new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                  temp_file, 0, kuint64max, base::Time()));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+                                  temp_file, 0, kuint64max, base::Time())));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -9218,9 +9220,9 @@
   };
 
   FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(fake_reader);
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(make_scoped_ptr(fake_reader));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -14673,9 +14675,10 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -14780,9 +14783,10 @@
   // Delete the transaction to release the socket back into the socket pool.
   trans1.reset();
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request2;
   request2.method = "POST";
@@ -14812,9 +14816,10 @@
 
 TEST_P(HttpNetworkTransactionTest,
        PostReadsErrorResponseAfterResetPartialBodySent) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -14867,8 +14872,6 @@
 // This tests the more common case than the previous test, where headers and
 // body are not merged into a single request.
 TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
   ChunkedUploadDataStream upload_data_stream(0);
 
   HttpRequestInfo request;
@@ -14926,9 +14929,10 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -14979,9 +14983,10 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -15021,9 +15026,10 @@
 
 TEST_P(HttpNetworkTransactionTest,
        PostIgnoresNonErrorResponseAfterResetAnd100) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -15064,9 +15070,10 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -15104,9 +15111,10 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -15326,9 +15334,10 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -15370,9 +15379,10 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -15415,8 +15425,6 @@
 }
 
 TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("foo", 3));
   ChunkedUploadDataStream upload_data_stream(0);
 
   HttpRequestInfo request;
diff --git a/net/http/http_stream_parser_unittest.cc b/net/http/http_stream_parser_unittest.cc
index b431549f..fbe964d 100644
--- a/net/http/http_stream_parser_unittest.cc
+++ b/net/http/http_stream_parser_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/run_loop.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
@@ -126,9 +127,9 @@
 }
 
 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_EmptyBody) {
-  ScopedVector<UploadElementReader> element_readers;
-  scoped_ptr<UploadDataStream> body(
-      new ElementsUploadDataStream(element_readers.Pass(), 0));
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  scoped_ptr<UploadDataStream> body(make_scoped_ptr(
+      new ElementsUploadDataStream(std::move(element_readers), 0)));
   ASSERT_EQ(OK, body->Init(CompletionCallback()));
   // Shouldn't be merged if upload data is empty.
   ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody(
@@ -153,14 +154,14 @@
   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &temp_file_path));
 
   {
-    ScopedVector<UploadElementReader> element_readers;
+    std::vector<scoped_ptr<UploadElementReader>> element_readers;
 
-    element_readers.push_back(
+    element_readers.push_back(make_scoped_ptr(
         new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                    temp_file_path, 0, 0, base::Time()));
+                                    temp_file_path, 0, 0, base::Time())));
 
     scoped_ptr<UploadDataStream> body(
-        new ElementsUploadDataStream(element_readers.Pass(), 0));
+        new ElementsUploadDataStream(std::move(element_readers), 0));
     TestCompletionCallback callback;
     ASSERT_EQ(ERR_IO_PENDING, body->Init(callback.callback()));
     ASSERT_EQ(OK, callback.WaitForResult());
@@ -174,13 +175,13 @@
 }
 
 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_SmallBodyInMemory) {
-  ScopedVector<UploadElementReader> element_readers;
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
   const std::string payload = "123";
-  element_readers.push_back(new UploadBytesElementReader(
-      payload.data(), payload.size()));
+  element_readers.push_back(make_scoped_ptr(
+      new UploadBytesElementReader(payload.data(), payload.size())));
 
   scoped_ptr<UploadDataStream> body(
-      new ElementsUploadDataStream(element_readers.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers), 0));
   ASSERT_EQ(OK, body->Init(CompletionCallback()));
   // Yes, should be merged if the in-memory body is small here.
   ASSERT_TRUE(HttpStreamParser::ShouldMergeRequestHeadersAndBody(
@@ -188,13 +189,13 @@
 }
 
 TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_LargeBodyInMemory) {
-  ScopedVector<UploadElementReader> element_readers;
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
   const std::string payload(10000, 'a');  // 'a' x 10000.
-  element_readers.push_back(new UploadBytesElementReader(
-      payload.data(), payload.size()));
+  element_readers.push_back(make_scoped_ptr(
+      new UploadBytesElementReader(payload.data(), payload.size())));
 
   scoped_ptr<UploadDataStream> body(
-      new ElementsUploadDataStream(element_readers.Pass(), 0));
+      new ElementsUploadDataStream(std::move(element_readers), 0));
   ASSERT_EQ(OK, body->Init(CompletionCallback()));
   // Shouldn't be merged if the in-memory body is large here.
   ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody(
@@ -333,9 +334,10 @@
   scoped_ptr<ClientSocketHandle> socket_handle =
       CreateConnectedSocketHandle(&data);
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(new UploadBytesElementReader("hello world!", 12));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(
+      make_scoped_ptr(new UploadBytesElementReader("hello world!", 12)));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
   ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback()));
 
   HttpRequestInfo request;
diff --git a/net/quic/quic_end_to_end_unittest.cc b/net/quic/quic_end_to_end_unittest.cc
index 39173d67..e2515ee 100644
--- a/net/quic/quic_end_to_end_unittest.cc
+++ b/net/quic/quic_end_to_end_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <vector>
+
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
@@ -199,12 +201,11 @@
   // Initializes |request_| for a post of |length| bytes.
   void InitializePostRequest(size_t length) {
     GenerateBody(length);
-    ScopedVector<UploadElementReader> element_readers;
-    element_readers.push_back(
-        new UploadBytesElementReader(request_body_.data(),
-                                     request_body_.length()));
+    std::vector<scoped_ptr<UploadElementReader>> element_readers;
+    element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
+        request_body_.data(), request_body_.length())));
     upload_data_stream_.reset(
-        new ElementsUploadDataStream(element_readers.Pass(), 0));
+        new ElementsUploadDataStream(std::move(element_readers), 0));
     request_.method = "POST";
     request_.url = GURL("https://test.example.com/");
     request_.upload_data_stream = upload_data_stream_.get();
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index 838f105d..6bc1af2 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -8,6 +8,7 @@
 
 #include <vector>
 
+#include "base/memory/scoped_ptr.h"
 #include "base/thread_task_runner_handle.h"
 #include "net/base/chunked_upload_data_stream.h"
 #include "net/base/elements_upload_data_stream.h"
@@ -518,10 +519,10 @@
 
   Initialize();
 
-  ScopedVector<UploadElementReader> element_readers;
-  element_readers.push_back(
-      new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  element_readers.push_back(make_scoped_ptr(
+      new UploadBytesElementReader(kUploadData, strlen(kUploadData))));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
   request_.method = "POST";
   request_.url = GURL("http://www.google.com/");
   request_.upload_data_stream = &upload_data_stream;
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index deebd64..0add3ff 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -9,7 +9,7 @@
 #include "base/bind_helpers.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/memory/scoped_vector.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/run_loop.h"
 #include "base/strings/string_piece.h"
 #include "base/test/test_file_util.h"
@@ -459,11 +459,11 @@
 
   const HttpRequestInfo& CreatePostRequest() {
     if (!post_request_initialized_) {
-      ScopedVector<UploadElementReader> element_readers;
-      element_readers.push_back(
-          new UploadBytesElementReader(kUploadData, kUploadDataSize));
+      std::vector<scoped_ptr<UploadElementReader>> element_readers;
+      element_readers.push_back(make_scoped_ptr(
+          new UploadBytesElementReader(kUploadData, kUploadDataSize)));
       upload_data_stream_.reset(
-          new ElementsUploadDataStream(element_readers.Pass(), 0));
+          new ElementsUploadDataStream(std::move(element_readers), 0));
 
       post_request_.method = "POST";
       post_request_.url = GURL(GetDefaultUrl());
@@ -480,12 +480,12 @@
       CHECK_EQ(static_cast<int>(kUploadDataSize),
                base::WriteFile(file_path, kUploadData, kUploadDataSize));
 
-      ScopedVector<UploadElementReader> element_readers;
-      element_readers.push_back(new UploadFileElementReader(
+      std::vector<scoped_ptr<UploadElementReader>> element_readers;
+      element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
           base::ThreadTaskRunnerHandle::Get().get(), file_path, 0,
-          kUploadDataSize, base::Time()));
+          kUploadDataSize, base::Time())));
       upload_data_stream_.reset(
-          new ElementsUploadDataStream(element_readers.Pass(), 0));
+          new ElementsUploadDataStream(std::move(element_readers), 0));
 
       post_request_.method = "POST";
       post_request_.url = GURL(GetDefaultUrl());
@@ -505,12 +505,12 @@
              base::WriteFile(file_path, kUploadData, kUploadDataSize));
     CHECK(base::MakeFileUnreadable(file_path));
 
-    ScopedVector<UploadElementReader> element_readers;
-    element_readers.push_back(new UploadFileElementReader(
+    std::vector<scoped_ptr<UploadElementReader>> element_readers;
+    element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
         base::ThreadTaskRunnerHandle::Get().get(), file_path, 0,
-        kUploadDataSize, base::Time()));
+        kUploadDataSize, base::Time())));
     upload_data_stream_.reset(
-        new ElementsUploadDataStream(element_readers.Pass(), 0));
+        new ElementsUploadDataStream(std::move(element_readers), 0));
 
     post_request_.method = "POST";
     post_request_.url = GURL(GetDefaultUrl());
@@ -530,17 +530,17 @@
       CHECK_EQ(static_cast<int>(kUploadDataSize),
                base::WriteFile(file_path, kUploadData, kUploadDataSize));
 
-      ScopedVector<UploadElementReader> element_readers;
-      element_readers.push_back(
-          new UploadBytesElementReader(kUploadData, kFileRangeOffset));
-      element_readers.push_back(new UploadFileElementReader(
+      std::vector<scoped_ptr<UploadElementReader>> element_readers;
+      element_readers.push_back(make_scoped_ptr(
+          new UploadBytesElementReader(kUploadData, kFileRangeOffset)));
+      element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
           base::ThreadTaskRunnerHandle::Get().get(), file_path,
-          kFileRangeOffset, kFileRangeLength, base::Time()));
-      element_readers.push_back(new UploadBytesElementReader(
+          kFileRangeOffset, kFileRangeLength, base::Time())));
+      element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
           kUploadData + kFileRangeOffset + kFileRangeLength,
-          kUploadDataSize - (kFileRangeOffset + kFileRangeLength)));
+          kUploadDataSize - (kFileRangeOffset + kFileRangeLength))));
       upload_data_stream_.reset(
-          new ElementsUploadDataStream(element_readers.Pass(), 0));
+          new ElementsUploadDataStream(std::move(element_readers), 0));
 
       post_request_.method = "POST";
       post_request_.url = GURL(GetDefaultUrl());
@@ -1947,8 +1947,8 @@
 TEST_P(SpdyNetworkTransactionTest, EmptyPost) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
   // Create an empty UploadDataStream.
-  ScopedVector<UploadElementReader> element_readers;
-  ElementsUploadDataStream stream(element_readers.Pass(), 0);
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
+  ElementsUploadDataStream stream(std::move(element_readers), 0);
 
   // Setup the request
   HttpRequestInfo request;
@@ -5844,12 +5844,12 @@
   DeterministicSocketData data(reads, arraysize(reads),
                                writes, arraysize(writes));
 
-  ScopedVector<UploadElementReader> element_readers;
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
   for (int i = 0; i < kFrameCount; ++i) {
-    element_readers.push_back(
-        new UploadBytesElementReader(content->c_str(), content->size()));
+    element_readers.push_back(make_scoped_ptr(
+        new UploadBytesElementReader(content->c_str(), content->size())));
   }
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   // Setup the request
   HttpRequestInfo request;
@@ -6058,12 +6058,12 @@
   DeterministicSocketData data(reads, arraysize(reads),
                                writes, arraysize(writes));
 
-  ScopedVector<UploadElementReader> element_readers;
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
   for (int i = 0; i < kFrameCount; ++i) {
-    element_readers.push_back(
-        new UploadBytesElementReader(content->c_str(), content->size()));
+    element_readers.push_back(make_scoped_ptr(
+        new UploadBytesElementReader(content->c_str(), content->size())));
   }
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   // Setup the request
   HttpRequestInfo request;
@@ -6166,12 +6166,12 @@
 
   SequencedSocketData data(reads, arraysize(reads), writes.get(), num_writes);
 
-  ScopedVector<UploadElementReader> element_readers;
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
   std::string upload_data_string(initial_window_size, 'a');
   upload_data_string.append(kUploadData, kUploadDataSize);
-  element_readers.push_back(new UploadBytesElementReader(
-      upload_data_string.c_str(), upload_data_string.size()));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
+      upload_data_string.c_str(), upload_data_string.size())));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -6281,12 +6281,12 @@
   DeterministicSocketData data(reads.data(), reads.size(), writes.data(),
                                writes.size());
 
-  ScopedVector<UploadElementReader> element_readers;
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
   std::string upload_data_string(initial_window_size, 'a');
   upload_data_string.append(kUploadData, kUploadDataSize);
-  element_readers.push_back(new UploadBytesElementReader(
-      upload_data_string.c_str(), upload_data_string.size()));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
+      upload_data_string.c_str(), upload_data_string.size())));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
@@ -6402,12 +6402,12 @@
   DeterministicSocketData data(reads.data(), reads.size(), writes.data(),
                                writes.size());
 
-  ScopedVector<UploadElementReader> element_readers;
+  std::vector<scoped_ptr<UploadElementReader>> element_readers;
   std::string upload_data_string(initial_window_size, 'a');
   upload_data_string.append(kUploadData, kUploadDataSize);
-  element_readers.push_back(new UploadBytesElementReader(
-      upload_data_string.c_str(), upload_data_string.size()));
-  ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+  element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
+      upload_data_string.c_str(), upload_data_string.size())));
+  ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
 
   HttpRequestInfo request;
   request.method = "POST";
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 5ffe31c..c72d5c2 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -5459,17 +5459,17 @@
     PathService::Get(base::DIR_EXE, &dir);
     base::SetCurrentDirectory(dir);
 
-    ScopedVector<UploadElementReader> element_readers;
+    std::vector<scoped_ptr<UploadElementReader>> element_readers;
 
     base::FilePath path;
     PathService::Get(base::DIR_SOURCE_ROOT, &path);
     path = path.Append(kTestFilePath);
     path = path.Append(FILE_PATH_LITERAL("with-headers.html"));
-    element_readers.push_back(
+    element_readers.push_back(make_scoped_ptr(
         new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
-                                    path, 0, kuint64max, base::Time()));
+                                    path, 0, kuint64max, base::Time())));
     r->set_upload(make_scoped_ptr<UploadDataStream>(
-        new ElementsUploadDataStream(element_readers.Pass(), 0)));
+        new ElementsUploadDataStream(std::move(element_readers), 0)));
 
     r->Start();
     EXPECT_TRUE(r->is_pending());
@@ -5504,15 +5504,15 @@
         http_test_server()->GetURL("/echo"), DEFAULT_PRIORITY, &d));
     r->set_method("POST");
 
-    ScopedVector<UploadElementReader> element_readers;
+    std::vector<scoped_ptr<UploadElementReader>> element_readers;
 
-    element_readers.push_back(new UploadFileElementReader(
+    element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
         base::ThreadTaskRunnerHandle::Get().get(),
         base::FilePath(FILE_PATH_LITERAL(
             "c:\\path\\to\\non\\existant\\file.randomness.12345")),
-        0, kuint64max, base::Time()));
+        0, kuint64max, base::Time())));
     r->set_upload(make_scoped_ptr<UploadDataStream>(
-        new ElementsUploadDataStream(element_readers.Pass(), 0)));
+        new ElementsUploadDataStream(std::move(element_readers), 0)));
 
     r->Start();
     EXPECT_TRUE(r->is_pending());
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 7e1272b8..f2d9d33 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -747,8 +747,8 @@
 crbug.com/492664 [ Mac ] imported/csswg-test/css-writing-modes-3/row-progression-007.xht [ Failure ]
 crbug.com/492664 [ Mac ] imported/csswg-test/css-writing-modes-3/row-progression-008.xht [ Failure ]
 crbug.com/492664 [ Mac ] imported/csswg-test/css-writing-modes-3/row-progression-009.xht [ Failure ]
-crbug.com/492664 [ Mac ] imported/csswg-test/css-writing-modes-3/text-baseline-006.xht [ Failure ]
-crbug.com/492664 [ Mac ] imported/csswg-test/css-writing-modes-3/text-baseline-007.xht [ Failure ]
+crbug.com/492664 [ Mac ] imported/csswg-test/css-writing-modes-3/text-baseline-vrl-006.xht [ Failure ]
+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 ]
 
@@ -1295,9 +1295,6 @@
 
 crbug.com/550285 [ XP ] virtual/syncpaint/inspector/tracing/decode-resize.html [ Slow Pass Failure ]
 
-crbug.com/560652 [ Mac ] editing/selection/vertical-rl-rtl-extend-line-forward-p.html [ Failure ]
-crbug.com/560652 [ Mac ] editing/selection/vertical-rl-rtl-extend-line-forward-br.html [ Failure ]
-
 crbug.com/474759 fast/writing-mode/vertical-rl-replaced-selection.html [ Failure ]
 crbug.com/474759 fast/block/line-layout/selection-highlight-overlap.html [ Failure ]
 crbug.com/502927 [ XP ] paint/frames/frameset-with-stacking-context-and-not-stacking-context-children.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations
index b95bde14..2ec4624 100644
--- a/third_party/WebKit/LayoutTests/W3CImportExpectations
+++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -501,6 +501,12 @@
 imported/csswg-test/css-writing-modes-3/line-box-direction-058.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/line-box-direction-059.xht [ Skip ]
 imported/csswg-test/css-writing-modes-3/line-box-direction-060.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/text-baseline-slr-009.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/text-baseline-slr-011.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/text-baseline-slr-013.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/text-baseline-srl-008.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/text-baseline-srl-010.xht [ Skip ]
+imported/csswg-test/css-writing-modes-3/text-baseline-srl-012.xht [ Skip ]
 
 # CSS Writing Modes Level 3: Following tests require applying writing-mode to table-cell, which we do not support today. crbug.com/409155
 imported/csswg-test/css-writing-modes-3/block-flow-direction-017.xht [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-factor-less-than-one.html b/third_party/WebKit/LayoutTests/css3/flexbox/flex-factor-less-than-one.html
new file mode 100644
index 0000000..dbeb0056
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/css3/flexbox/flex-factor-less-than-one.html
@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+<link href="resources/flexbox.css" rel="stylesheet">
+<style>
+.container {
+  height: 100px;
+  width: 100px;
+  border: 1px solid black;
+}
+
+.child-flex-grow-0-75 {
+  background-color: lime;
+  flex-grow: 0.75;
+}
+
+.child-flex-grow-0-5 {
+  background-color: green;
+  flex-grow: 0.5;
+}
+
+.child-flex-grow-0-25 {
+  background-color: red;
+  flex-grow: 0.25;
+}
+
+.child-flex-shrink-0-5 {
+  background-color: green;
+  flex-shrink: 0.5;
+  width: 200px;
+  height: 200px;
+}
+
+.child-flex-shrink-0-25 {
+  background-color: red;
+  flex-shrink: 0.25;
+  width: 200px;
+  height: 200px;
+}
+
+.basis-0 {
+  flex-basis: 0;
+}
+
+.basis {
+  flex-basis: 30px;
+}
+
+.basis-big {
+  flex-basis: 100px;
+}
+
+.vertical {
+  writing-mode: vertical-rl;
+}
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../resources/check-layout-th.js"></script>
+<body onload="checkLayout('.flexbox');">
+<div id=log></div>
+
+<div class="flexbox container">
+  <div class="child-flex-grow-0-5" data-expected-width="50"></div>
+</div>
+
+<div class="flexbox container">
+  <div class="child-flex-grow-0-5" data-expected-width="50"></div>
+  <div class="child-flex-grow-0-25" data-expected-width="25"></div>
+</div>
+
+<div class="flexbox container column">
+  <div class="child-flex-grow-0-5" data-expected-height="50"></div>
+  <div class="child-flex-grow-0-25" data-expected-height="25"></div>
+</div>
+
+<div class="flexbox container column vertical">
+  <div class="child-flex-grow-0-5 " data-expected-width="50"></div>
+  <div class="child-flex-grow-0-25 " data-expected-width="25"></div>
+</div>
+
+<div class="flexbox container vertical">
+  <div class="child-flex-grow-0-5 " data-expected-height="50"></div>
+  <div class="child-flex-grow-0-25 " data-expected-height="25"></div>
+</div>
+
+<div class="flexbox container">
+  <div class="child-flex-grow-0-5 basis" data-expected-width="50"></div>
+  <div class="child-flex-grow-0-25 basis" data-expected-width="40"></div>
+ </div>
+ 
+<div class="flexbox container column">
+  <div class="child-flex-grow-0-5 basis" data-expected-height="50"></div>
+  <div class="child-flex-grow-0-25 basis" data-expected-height="40"></div>
+</div>
+
+<div class="flexbox container vertical">
+  <div class="child-flex-grow-0-5 basis" data-expected-height="50"></div>
+  <div class="child-flex-grow-0-25 basis" data-expected-height="40"></div>
+</div>
+
+<div class="flexbox container column vertical">
+  <div class="child-flex-grow-0-5 basis" data-expected-width="50"></div>
+  <div class="child-flex-grow-0-25 basis" data-expected-width="40"></div>
+</div>
+
+<!-- And now, the shrink cases -->
+<div class="flexbox container">
+  <div class="child-flex-shrink-0-5" data-expected-width="150"></div>
+</div>
+
+<div class="flexbox container">
+  <div class="child-flex-shrink-0-5" data-expected-width="50"></div>
+  <div class="child-flex-shrink-0-25" data-expected-width="125"></div>
+</div>
+
+<div class="flexbox container column">
+  <div class="child-flex-shrink-0-5" data-expected-height="50"></div>
+  <div class="child-flex-shrink-0-25" data-expected-height="125"></div>
+</div>
+
+<div class="flexbox container column vertical">
+  <div class="child-flex-shrink-0-5 " data-expected-width="50"></div>
+  <div class="child-flex-shrink-0-25 " data-expected-width="125"></div>
+</div>
+
+<div class="flexbox container vertical">
+  <div class="child-flex-shrink-0-5 " data-expected-height="50"></div>
+  <div class="child-flex-shrink-0-25 " data-expected-height="125"></div>
+</div>
+
+<div class="flexbox container">
+  <div class="child-flex-shrink-0-5 basis-big" data-expected-width="50"></div>
+  <div class="child-flex-shrink-0-25 basis-big" data-expected-width="75"></div>
+ </div>
+ 
+<div class="flexbox container column">
+  <div class="child-flex-shrink-0-5 basis-big" data-expected-height="50"></div>
+  <div class="child-flex-shrink-0-25 basis-big" data-expected-height="75"></div>
+</div>
+
+<div class="flexbox container vertical">
+  <div class="child-flex-shrink-0-5 basis-big" data-expected-height="50"></div>
+  <div class="child-flex-shrink-0-25 basis-big" data-expected-height="75"></div>
+</div>
+
+<div class="flexbox container column vertical">
+  <div class="child-flex-shrink-0-5 basis-big" data-expected-width="50"></div>
+  <div class="child-flex-shrink-0-25 basis-big" data-expected-width="75"></div>
+</div>
+
+<!-- Interaction of min-width: auto with fractional flex basis -->
+<div class="flexbox container" style="background-color: red;">
+  <div class="child-flex-grow-0-25 basis-0" style="background-color: green;" data-expected-width="10"></div>
+  <div class="child-flex-grow-0-75 basis-0" data-expected-width="90">
+    <div style="width: 90px;"></div>
+  </div>
+</div>
+
+</body>
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flex-grow-less-than-one.html b/third_party/WebKit/LayoutTests/css3/flexbox/flex-grow-less-than-one.html
deleted file mode 100644
index 1f2b856..0000000
--- a/third_party/WebKit/LayoutTests/css3/flexbox/flex-grow-less-than-one.html
+++ /dev/null
@@ -1,77 +0,0 @@
-<!DOCTYPE html>
-<link href="resources/flexbox.css" rel="stylesheet">
-<style>
-.container {
-  height: 100px;
-  width: 100px;
-  border: 1px solid black;
-}
-
-.child-flex-grow-0-5 {
-  background-color: green;
-  flex-grow: 0.5;
-}
-
-.child-flex-grow-0-25 {
-  background-color: red;
-  flex-grow: 0.25;
-}
-
-.basis {
-  flex-basis: 30px;
-}
-
-.vertical {
-  -webkit-writing-mode: vertical-rl;
-}
-</style>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../../resources/check-layout-th.js"></script>
-<body onload="checkLayout('.flexbox');">
-<div id=log></div>
-
-<div class="flexbox container">
-  <div class="child-flex-grow-0-5" data-expected-width="50"></div>
-</div>
-
-<div class="flexbox container">
-  <div class="child-flex-grow-0-5" data-expected-width="50"></div>
-  <div class="child-flex-grow-0-25" data-expected-width="25"></div>
-</div>
-
-<div class="flexbox container column">
-  <div class="child-flex-grow-0-5" data-expected-height="50"></div>
-  <div class="child-flex-grow-0-25" data-expected-height="25"></div>
-</div>
-
-<div class="flexbox container column vertical">
-  <div class="child-flex-grow-0-5 " data-expected-width="50"></div>
-  <div class="child-flex-grow-0-25 " data-expected-width="25"></div>
-</div>
-
-<div class="flexbox container vertical">
-  <div class="child-flex-grow-0-5 " data-expected-height="50"></div>
-  <div class="child-flex-grow-0-25 " data-expected-height="25"></div>
-</div>
-
-<div class="flexbox container">
-  <div class="child-flex-grow-0-5 basis" data-expected-width="50"></div>
-  <div class="child-flex-grow-0-25 basis" data-expected-width="40"></div>
- </div>
- 
-<div class="flexbox container column">
-  <div class="child-flex-grow-0-5 basis" data-expected-height="50"></div>
-  <div class="child-flex-grow-0-25 basis" data-expected-height="40"></div>
-</div>
-
-<div class="flexbox container vertical">
-  <div class="child-flex-grow-0-5 basis" data-expected-height="50"></div>
-  <div class="child-flex-grow-0-25 basis" data-expected-height="40"></div>
-</div>
-
-<div class="flexbox container column vertical">
-  <div class="child-flex-grow-0-5 basis" data-expected-width="50"></div>
-  <div class="child-flex-grow-0-25 basis" data-expected-width="40"></div>
-</div>
-</body>
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-001.html b/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-001.html
index 9b8adc1..3c77c81b 100644
--- a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-001.html
+++ b/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-001.html
@@ -1,60 +1,31 @@
-<html> 
-<head>
-
-<style>
-.editing { 
-    border: 2px solid red; 
-    font-size: 24px; 
-}
-.explanation { 
-    border: 2px solid blue; 
-    padding: 12px; 
-    font-size: 24px; 
-    margin-bottom: 24px;
-}
-.scenario { margin-bottom: 16px;}
-.scenario:first-line { font-weight: bold; margin-bottom: 16px;}
-.expected-results:first-line { font-weight: bold }
-</style>
-<script src=../editing.js language="JavaScript" type="text/JavaScript" ></script>
-
-<script>
-
-function editingTest() {
-    doubleClickAtSelectionStart();
-    deleteCommand();
-}
-
-</script>
-
-<title>Editing Test</title> 
-</head> 
-<body>
-
-<div class="explanation">
-<div class="scenario">
-Tests: 
-<br>
-Smart delete when deleting the first word on a line.
-</div>
-<div class="expected-results">
-Expected Results:
-<br>
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<div>
 The first word and the space following the first word should be deleted. It should like this this:
-<BR>
+<br>
 bar baz
 </div>
-</div>
-
 <div contenteditable id="root" style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space;">
-<div id="test" class="editing">
-foo bar baz
+<div id="sample" contenteditable>foo bar baz</div>
 </div>
-</div>
-
+<div id="log"></div>
 <script>
-runEditingTest();
+test(function() {
+    if (window.internals)
+        internals.settings.setEditingBehavior('win');
+    var selection = window.getSelection();
+    var sample = document.getElementById('sample');
+    selection.collapse(sample.firstChild, 0);
+    var rect = selection.getRangeAt(0).getClientRects()[0];
+    if (!window.eventSender)
+        return;
+    eventSender.mouseMoveTo(rect.left, rect.top);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+    document.execCommand('delete');
+    assert_equals(sample.textContent, 'bar baz');
+});
 </script>
-
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-002.html b/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-002.html
index 9430ee2..1471051 100644
--- a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-002.html
+++ b/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-002.html
@@ -1,64 +1,31 @@
-<html> 
-<head>
-
-<style>
-.editing { 
-    border: 2px solid red; 
-    font-size: 24px; 
-}
-.explanation { 
-    border: 2px solid blue; 
-    padding: 12px; 
-    font-size: 24px; 
-    margin-bottom: 24px;
-}
-.scenario { margin-bottom: 16px;}
-.scenario:first-line { font-weight: bold; margin-bottom: 16px;}
-.expected-results:first-line { font-weight: bold }
-</style>
-<script src=../editing.js language="JavaScript" type="text/JavaScript" ></script>
-
-<script>
-
-function editingTest() {
-    if (window.internals)
-        internals.settings.setEditingBehavior('mac');
-    moveSelectionForwardByWordCommand();
-    moveSelectionForwardByCharacterCommand();
-    doubleClickAtSelectionStart();
-    deleteCommand();
-}
-
-</script>
-
-<title>Editing Test</title> 
-</head> 
-<body>
-
-<div class="explanation">
-<div class="scenario">
-Tests: 
-<br>
-Smart delete when deleting the second word of a line.
-</div>
-<div class="expected-results">
-Expected Results:
-<br>
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<div>
 The second word and the space before the second word should be deleted. It should like this this:
-<BR>
-foo baz
+<br>
+foo bar
 </div>
-</div>
-
 <div contenteditable id="root" style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space;">
-<div id="test" class="editing">
-foo bar baz
+<div id="sample" contenteditable>foo bar baz</div>
 </div>
-</div>
-
+<div id="log"></div>
 <script>
-runEditingTest();
+test(function() {
+    if (window.internals)
+        internals.settings.setEditingBehavior('win');
+    var selection = window.getSelection();
+    var sample = document.getElementById('sample');
+    selection.collapse(sample.firstChild, 4);
+    var rect = selection.getRangeAt(0).getClientRects()[0];
+    if (!window.eventSender)
+        return;
+    eventSender.mouseMoveTo(rect.left, rect.top);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+    document.execCommand('delete');
+    assert_equals(sample.textContent, 'foo baz');
+});
 </script>
-
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-003-expected.txt b/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-003-expected.txt
deleted file mode 100644
index fd8ccd58..0000000
--- a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-003-expected.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Test for smart delete backward on double click selected word.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-includeSpace
-PASS sample.innerText is "foo baz"
-PASS getSelection().rangeCount is 1
-PASS getSelection().focusNode is sample.firstChild
-PASS getSelection().focusOffset is 4
-notIncludeSpace
-PASS sample.innerText is "foo baz"
-PASS getSelection().rangeCount is 1
-PASS getSelection().focusNode is sample.firstChild
-PASS getSelection().focusOffset is 3
-PASS successfullyParsed is true
-
-TEST COMPLETE
-Please tun this test with DRT.
-
-To run it manually, double click on 'bar' and hit delete. You should see 'foo baz'.
-
-foo baz
-foo baz
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-003.html b/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-003.html
index 87647da..da9573f 100644
--- a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-003.html
+++ b/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-003.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html>
-<script src="../../resources/js-test.js"></script>
-<p>Please tun this test with DRT.</p>
-<p>To run it manually, double click on 'bar' and hit delete.  You should see 'foo baz'.</p>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<h1>Test for smart delete backward on double click selected word.</h1>
+<p>Please tun this test with layout test runner</p>
+<p>To run it manually, double click on 'bar' and hit backspace.  You should see 'foo baz'.</p>
 <div id="includeSpace" contenteditable="true">foo b<span id="target">a</span>r baz</div>
 <div id="notIncludeSpace" contenteditable="true">foo b<span id="target">a</span>r baz</div>
+<div id="log"></div>
 <script>
-description('Test for smart delete backward on double click selected word.');
-var sample;
 function testIt(sampleId, expectedString, expectedOffset) {
-    if (!window.testRunner)
+    if (!window.eventSender || !window.internals || window.testRunner)
       return;
-    sample = document.getElementById(sampleId);
+    var selection = window.getSelection();
+    var sample = document.getElementById(sampleId);
     var target = sample.querySelector('#target');
     internals.settings.setSelectTrailingWhitespaceEnabled(sampleId == 'includeSpace');
     eventSender.mouseMoveTo(target.offsetLeft, target.offsetTop);
@@ -18,13 +20,12 @@
     eventSender.mouseUp();
     eventSender.mouseDown();
     eventSender.mouseUp();
-    debug(sampleId);
     testRunner.execCommand('DeleteBackward');
-    shouldBeEqualToString('sample.innerText', expectedString);
-    shouldBe('getSelection().rangeCount', '1');
-    shouldBe('getSelection().focusNode',  'sample.firstChild');
-    shouldBe('getSelection().focusOffset', expectedOffset.toString());
+    assert_equals(sample.innerText, expectedString, sampleId);
+    assert_true(selection.isCollapsed);
+    assert_equals(selection.focusNode,  sample.firstChild, sampleId + ' focusNode');
+    assert_equals(selection.focusOffset, expectedOffset,  sample.firstChild, sampleId + ' focusOffset');
 }
-testIt('includeSpace', 'foo baz', 4);
-testIt('notIncludeSpace', 'foo\u00A0baz', 3);
+test(testIt.bind(this, 'includeSpace', 'foo baz', 4), 'includeSpace');
+test(testIt.bind(this, 'notIncludeSpace', 'foo\u00A0baz', 3), 'notIncludeSpace');
 </script>
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-004-expected.txt b/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-004-expected.txt
deleted file mode 100644
index 25732ca2..0000000
--- a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-004-expected.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Test for smart delete forward on double click selected word.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-includeSpace
-PASS sample.innerText is "foo baz"
-PASS getSelection().rangeCount is 1
-PASS getSelection().focusNode is sample.firstChild
-PASS getSelection().focusOffset is 4
-notIncludeSpace
-PASS sample.innerText is "foo baz"
-PASS getSelection().rangeCount is 1
-PASS getSelection().focusNode is sample.firstChild
-PASS getSelection().focusOffset is 3
-PASS successfullyParsed is true
-
-TEST COMPLETE
-Please tun this test with DRT.
-
-To run it manually, double click on 'bar' and hit delete. You should see 'foo baz'.
-
-foo baz
-foo baz
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-004.html b/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-004.html
index 7ebfcb9..d74a079 100644
--- a/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-004.html
+++ b/third_party/WebKit/LayoutTests/editing/deleting/smart-delete-004.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html>
-<script src="../../resources/js-test.js"></script>
-<p>Please tun this test with DRT.</p>
-<p>To run it manually, double click on 'bar' and hit delete.  You should see 'foo baz'.</p>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<h1>Test for smart delete backward on double click selected word.</h1>
+<p>Please tun this test with layout test runner</p>
+<p>To run it manually, double click on 'bar' and hit backspace.  You should see 'foo baz'.</p>
 <div id="includeSpace" contenteditable="true">foo b<span id="target">a</span>r baz</div>
 <div id="notIncludeSpace" contenteditable="true">foo b<span id="target">a</span>r baz</div>
+<div id="log"></div>
 <script>
-description('Test for smart delete forward on double click selected word.');
-var sample;
 function testIt(sampleId, expectedString, expectedOffset) {
-    if (!window.testRunner)
+    if (!window.eventSender || !window.internals || window.testRunner)
       return;
-    sample = document.getElementById(sampleId);
+    var selection = window.getSelection();
+    var sample = document.getElementById(sampleId);
     var target = sample.querySelector('#target');
     internals.settings.setSelectTrailingWhitespaceEnabled(sampleId == 'includeSpace');
     eventSender.mouseMoveTo(target.offsetLeft, target.offsetTop);
@@ -18,13 +20,12 @@
     eventSender.mouseUp();
     eventSender.mouseDown();
     eventSender.mouseUp();
-    debug(sampleId);
     testRunner.execCommand('DeleteForward');
-    shouldBeEqualToString('sample.innerText', expectedString);
-    shouldBe('getSelection().rangeCount', '1');
-    shouldBe('getSelection().focusNode',  'sample.firstChild');
-    shouldBe('getSelection().focusOffset', expectedOffset.toString());
+    assert_equals(sample.innerText, expectedString, sampleId);
+    assert_true(selection.isCollapsed);
+    assert_equals(selection.focusNode,  sample.firstChild, sampleId + ' focusNode');
+    assert_equals(selection.focusOffset, expectedOffset,  sample.firstChild, sampleId + ' focusOffset');
 }
-testIt('includeSpace', 'foo baz', 4);
-testIt('notIncludeSpace', 'foo\u00A0baz', 3);
+test(testIt.bind(this, 'includeSpace', 'foo baz', 4), 'includeSpace');
+test(testIt.bind(this, 'notIncludeSpace', 'foo\u00A0baz', 3), 'notIncludeSpace');
 </script>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/vertical-rl-rtl-extend-line-forward-br.html b/third_party/WebKit/LayoutTests/editing/selection/vertical-rl-rtl-extend-line-forward-br.html
index 3830f4a..082442d8 100644
--- a/third_party/WebKit/LayoutTests/editing/selection/vertical-rl-rtl-extend-line-forward-br.html
+++ b/third_party/WebKit/LayoutTests/editing/selection/vertical-rl-rtl-extend-line-forward-br.html
@@ -3,7 +3,7 @@
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
 <p>This tests horizontal caret movement in vertical writing mode.</p>
-<div id="test" style="font-family: monospace; font-size: 20px; height: 15ex; -webkit-writing-mode: vertical-rl; -webkit-text-orientation: sideways-right; outline: none;" contenteditable>
+<div id="test" style="font-family: Courier New; font-size: 20px; height: 15ex; -webkit-writing-mode: vertical-rl; -webkit-text-orientation: sideways-right; outline: none;" contenteditable>
 <p id="p1" dir="rtl">אני חתול.<br>אין לי שם.</p>
 </div>
 <div id="log"></div>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/vertical-rl-rtl-extend-line-forward-p.html b/third_party/WebKit/LayoutTests/editing/selection/vertical-rl-rtl-extend-line-forward-p.html
index 494366b..5ac8958 100644
--- a/third_party/WebKit/LayoutTests/editing/selection/vertical-rl-rtl-extend-line-forward-p.html
+++ b/third_party/WebKit/LayoutTests/editing/selection/vertical-rl-rtl-extend-line-forward-p.html
@@ -3,7 +3,7 @@
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
 <p>This tests horizontal caret movement in vertical writing mode.</p>
-<div id="test" style="font-family: monospace; font-size: 20px; height: 15ex; -webkit-writing-mode: vertical-rl;-webkit-text-orientation:sideways-right;text-rendering:optimizeLegibility; outline: none;" contenteditable>
+<div id="test" style="font-family: Courier New; font-size: 20px; height: 15ex; -webkit-writing-mode: vertical-rl;-webkit-text-orientation:sideways-right;text-rendering:optimizeLegibility; outline: none;" contenteditable>
 <p id="p1" dir="rtl">אני חתול.</p><p id="p2" dir="rtl">אין לי שם.</p>
 </div>
 <div id="log"></div>
diff --git a/third_party/WebKit/LayoutTests/fast/html/link-clear-sheet-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/html/link-clear-sheet-crash-expected.txt
new file mode 100644
index 0000000..0724b25
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/html/link-clear-sheet-crash-expected.txt
@@ -0,0 +1 @@
+PASS if not crashed
diff --git a/third_party/WebKit/LayoutTests/fast/html/link-clear-sheet-crash.html b/third_party/WebKit/LayoutTests/fast/html/link-clear-sheet-crash.html
new file mode 100644
index 0000000..48061e6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/html/link-clear-sheet-crash.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<link href="notexist.css" id="link" rel="stylesheet">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+onload = function(){
+    setTimeout(function(){
+        document.body.offsetTop;
+        link.setAttribute("sizes", "");
+        link.setAttribute("disabled", "");
+        requestAnimationFrame(function(){
+            if (window.testRunner)
+                testRunner.notifyDone();
+        });
+    }, 0);
+};
+</script>
+<p>PASS if not crashed</p>
diff --git a/third_party/WebKit/LayoutTests/fast/text/bidi-embedding-pop-and-push-same.html b/third_party/WebKit/LayoutTests/fast/text/bidi-embedding-pop-and-push-same.html
index 3515f3b..ae521d1b 100644
--- a/third_party/WebKit/LayoutTests/fast/text/bidi-embedding-pop-and-push-same.html
+++ b/third_party/WebKit/LayoutTests/fast/text/bidi-embedding-pop-and-push-same.html
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js
index 541713bc5..c5c7998c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js
@@ -169,7 +169,7 @@
         if (typeof status === "string")
             caption = status;
         else
-            caption = status.textContent;
+            caption = status.deepTextContent();
         if (callFrames)
             step1();
     }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js
index a79d9c67d..a0dbaf1c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/elements-test.js
@@ -969,14 +969,10 @@
 
 InspectorTest.dumpAnimationTimeline = function(timeline)
 {
-    for (var nodeUI of timeline._nodesMap.values()) {
-        for (nodeRow of nodeUI._rows) {
-            for (var ui of nodeRow.animations) {
-                InspectorTest.addResult(ui.animation().type());
-                InspectorTest.addResult(ui._nameElement.innerHTML);
-                InspectorTest.addResult(ui._svg.innerHTML);
-            }
-        }
+    for (var ui of timeline._uiAnimations) {
+        InspectorTest.addResult(ui.animation().type());
+        InspectorTest.addResult(ui._nameElement.innerHTML);
+        InspectorTest.addResult(ui._svg.innerHTML);
     }
 }
 
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-003-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-003-expected.xht
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-003-expected.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-003-expected.xht
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-003.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-003.xht
similarity index 95%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-003.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-003.xht
index cdb630a..37fe116 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-003.xht
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-003.xht
@@ -5,7 +5,7 @@
     <link rel="author" title="Hajime Shiozawa" href="mailto:hajime.shiozawa@gmail.com" />
     <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!--  2015-09-26  -->
     <link rel="help" title="4.2. Text Baseline" href="http://www.w3.org/TR/css-writing-modes-3/#text-baselines" />
-    <link rel="match" href="text-baseline-002-ref.xht" />
+    <link rel="match" href="text-baseline-vrl-002-ref.xht" />
     <meta name="assert" content="This test checks the generation of text baseline. When 'writing-mode' is 'vertical-lr' and when 'text-orientation' is 'mixed', then the central baseline is used as the dominant baseline." />
     <meta name="flags" content="ahem" />
     <style type="text/css"><![CDATA[
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-005-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-005-expected.xht
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-005-expected.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-005-expected.xht
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-005.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-005.xht
similarity index 95%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-005.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-005.xht
index 1f2f304..4a10b43f 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-005.xht
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-005.xht
@@ -5,7 +5,7 @@
     <link rel="author" title="Hajime Shiozawa" href="mailto:hajime.shiozawa@gmail.com" />
     <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!--  2015-09-26  -->
     <link rel="help" title="4.2. Text Baseline" href="http://www.w3.org/TR/css-writing-modes-3/#text-baselines" />
-    <link rel="match" href="text-baseline-002-ref.xht" />
+    <link rel="match" href="text-baseline-vrl-002-ref.xht" />
     <meta name="assert" content="This test checks the generation of text baseline. When 'writing-mode' is 'vertical-lr' and when 'text-orientation' is 'upright', then the central baseline is used as the dominant baseline." />
     <meta name="flags" content="ahem" />
     <style type="text/css"><![CDATA[
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-007-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-007-expected.xht
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-007-expected.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-007-expected.xht
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-007.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-007.xht
similarity index 95%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-007.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-007.xht
index 8e7007f..6ade11f16 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-007.xht
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vlr-007.xht
@@ -5,7 +5,7 @@
     <link rel="author" title="Hajime Shiozawa" href="mailto:hajime.shiozawa@gmail.com" />
     <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!--  2015-09-26  -->
     <link rel="help" title="4.2. Text Baseline" href="http://www.w3.org/TR/css-writing-modes-3/#text-baselines" />
-    <link rel="match" href="text-baseline-006-ref.xht" />
+    <link rel="match" href="text-baseline-vrl-006-ref.xht" />
     <meta name="assert" content="This test checks the generation of text baseline. When 'writing-mode' is 'vertical-lr' and when 'text-orientation' is 'sideways', then the alphabetical baseline is used as the dominant baseline." />
     <meta name="flags" content="ahem" />
     <style type="text/css"><![CDATA[
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-002-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-002-expected.xht
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-002-expected.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-002-expected.xht
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-002.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-002.xht
similarity index 95%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-002.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-002.xht
index 571d22e..a4202575 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-002.xht
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-002.xht
@@ -5,7 +5,7 @@
     <link rel="author" title="Hajime Shiozawa" href="mailto:hajime.shiozawa@gmail.com" />
     <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!--  2015-09-26  -->
     <link rel="help" title="4.2. Text Baseline" href="http://www.w3.org/TR/css-writing-modes-3/#text-baselines" />
-    <link rel="match" href="text-baseline-002-ref.xht" />
+    <link rel="match" href="text-baseline-vrl-002-ref.xht" />
     <meta name="assert" content="This test checks the generation of text baseline. When 'writing-mode' is 'vertical-rl' and when 'text-orientation' is 'mixed', then the central baseline is used as the dominant baseline." />
     <meta name="flags" content="ahem" />
     <style type="text/css"><![CDATA[
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-004-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-004-expected.xht
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-004-expected.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-004-expected.xht
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-004.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-004.xht
similarity index 95%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-004.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-004.xht
index ed60f37..e54e2d7 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-004.xht
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-004.xht
@@ -5,7 +5,7 @@
     <link rel="author" title="Hajime Shiozawa" href="mailto:hajime.shiozawa@gmail.com" />
     <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!--  2015-09-26  -->
     <link rel="help" title="4.2. Text Baseline" href="http://www.w3.org/TR/css-writing-modes-3/#text-baselines" />
-    <link rel="match" href="text-baseline-002-ref.xht" />
+    <link rel="match" href="text-baseline-vrl-002-ref.xht" />
     <meta name="assert" content="This test checks the generation of text baseline. When 'writing-mode' is 'vertical-rl' and when 'text-orientation' is 'upright', then the central baseline is used as the dominant baseline." />
     <meta name="flags" content="ahem" />
     <style type="text/css"><![CDATA[
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-006-expected.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-006-expected.xht
similarity index 100%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-006-expected.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-006-expected.xht
diff --git a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-006.xht b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-006.xht
similarity index 95%
rename from third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-006.xht
rename to third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-006.xht
index 83e374cc..c9f2897 100644
--- a/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-006.xht
+++ b/third_party/WebKit/LayoutTests/imported/csswg-test/css-writing-modes-3/text-baseline-vrl-006.xht
@@ -5,7 +5,7 @@
     <link rel="author" title="Hajime Shiozawa" href="mailto:hajime.shiozawa@gmail.com" />
     <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!--  2015-09-26  -->
     <link rel="help" title="4.2. Text Baseline" href="http://www.w3.org/TR/css-writing-modes-3/#text-baselines" />
-    <link rel="match" href="text-baseline-006-ref.xht" />
+    <link rel="match" href="text-baseline-vrl-006-ref.xht" />
     <meta name="assert" content="This test checks the generation of text baseline. When 'writing-mode' is 'vertical-rl' and when 'text-orientation' is 'sideways', then the alphabetical baseline is used as the dominant baseline." />
     <meta name="flags" content="ahem" />
     <style type="text/css"><![CDATA[
diff --git a/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline-expected.txt b/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline-expected.txt
index d52a226..3facea2 100644
--- a/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline-expected.txt
@@ -3,21 +3,51 @@
 >>>> Animation with start delay only
 WebAnimation
 
-<g style="transform: translateX(222.22px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="451.44" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.02 10.85 L 0.94 10.85 L 3.51 10.85 L 7.66 10.85 L 13.28 10.85 L 20.28 10.85 L 28.59 10.85 L 38.10 10.85 L 48.73 10.85 L 60.39 10.85 L 72.99 10.85 L 86.44 10.85 L 100.65 10.85 L 115.54 10.85 L 131.00 10.85 L 146.95 10.85 L 163.31 10.85 L 179.98 10.85 L 196.87 10.85 L 213.90 10.85 L 230.96 10.85 L 247.99 10.85 L 264.88 10.85 L 281.54 10.85 L 297.89 10.85 L 313.83 10.85 L 329.28 10.85 L 344.15 10.85 L 358.34 10.85 L 371.77 10.85 L 384.35 10.85 L 395.99 10.85 L 406.60 10.85 L 416.08 10.85 L 424.36 10.85 L 431.33 10.85 L 436.92 10.85 L 441.03 10.85 L 443.56 10.85 L 444.44 10.85 L 444.44 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="451.44" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="229.22" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(666.67px);"></line>
+<g style="transform: translateX(200px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="407.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.02 10.85 L 0.85 10.85 L 3.16 10.85 L 6.89 10.85 L 11.95 10.85 L 18.25 10.85 L 25.73 10.85 L 34.29 10.85 L 43.86 10.85 L 54.35 10.85 L 65.69 10.85 L 77.80 10.85 L 90.59 10.85 L 103.98 10.85 L 117.90 10.85 L 132.26 10.85 L 146.98 10.85 L 161.98 10.85 L 177.18 10.85 L 192.51 10.85 L 207.87 10.85 L 223.19 10.85 L 238.39 10.85 L 253.39 10.85 L 268.10 10.85 L 282.45 10.85 L 296.35 10.85 L 309.73 10.85 L 322.51 10.85 L 334.60 10.85 L 345.92 10.85 L 356.39 10.85 L 365.94 10.85 L 374.48 10.85 L 381.92 10.85 L 388.20 10.85 L 393.23 10.85 L 396.92 10.85 L 399.21 10.85 L 400.00 10.85 L 400.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="407.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="207.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(600px);"></line>
 >>>> Animation with start and end delay
 WebAnimation
 
-<g style="transform: translateX(3.28px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="663.81" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.03 10.85 L 1.39 10.85 L 5.19 10.85 L 11.32 10.85 L 19.62 10.85 L 29.97 10.85 L 42.25 10.85 L 56.31 10.85 L 72.02 10.85 L 89.25 10.85 L 107.87 10.85 L 127.75 10.85 L 148.75 10.85 L 170.74 10.85 L 193.59 10.85 L 217.17 10.85 L 241.34 10.85 L 265.98 10.85 L 290.94 10.85 L 316.10 10.85 L 341.33 10.85 L 366.49 10.85 L 391.44 10.85 L 416.07 10.85 L 440.23 10.85 L 463.79 10.85 L 486.62 10.85 L 508.59 10.85 L 529.57 10.85 L 549.42 10.85 L 568.01 10.85 L 585.21 10.85 L 600.88 10.85 L 614.90 10.85 L 627.13 10.85 L 637.44 10.85 L 645.70 10.85 L 651.76 10.85 L 655.51 10.85 L 656.81 10.85 L 656.81 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="663.81" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="10.28" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="13.57" style="stroke: black; transform: translateX(660.1px);"></line>
+<g style="transform: translateX(4.95px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="16.90" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.00 10.85 L 0.02 10.85 L 0.08 10.85 L 0.17 10.85 L 0.30 10.85 L 0.45 10.85 L 0.64 10.85 L 0.85 10.85 L 1.09 10.85 L 1.35 10.85 L 1.63 10.85 L 1.93 10.85 L 2.24 10.85 L 2.57 10.85 L 2.92 10.85 L 3.27 10.85 L 3.64 10.85 L 4.01 10.85 L 4.39 10.85 L 4.77 10.85 L 5.15 10.85 L 5.52 10.85 L 5.90 10.85 L 6.27 10.85 L 6.64 10.85 L 6.99 10.85 L 7.34 10.85 L 7.67 10.85 L 7.98 10.85 L 8.28 10.85 L 8.56 10.85 L 8.82 10.85 L 9.06 10.85 L 9.27 10.85 L 9.45 10.85 L 9.61 10.85 L 9.73 10.85 L 9.82 10.85 L 9.88 10.85 L 9.90 10.85 L 9.90 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="16.90" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="11.95" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(14.85px);"></line>
+WebAnimation
+
+<g style="transform: translateX(4.95px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="997.10" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.05 10.85 L 2.09 10.85 L 7.83 10.85 L 17.06 10.85 L 29.58 10.85 L 45.18 10.85 L 63.68 10.85 L 84.88 10.85 L 108.56 10.85 L 134.54 10.85 L 162.61 10.85 L 192.57 10.85 L 224.23 10.85 L 257.38 10.85 L 291.83 10.85 L 327.37 10.85 L 363.81 10.85 L 400.94 10.85 L 438.57 10.85 L 476.50 10.85 L 514.53 10.85 L 552.45 10.85 L 590.07 10.85 L 627.19 10.85 L 663.61 10.85 L 699.13 10.85 L 733.55 10.85 L 766.67 10.85 L 798.29 10.85 L 828.21 10.85 L 856.23 10.85 L 882.16 10.85 L 905.79 10.85 L 926.92 10.85 L 945.36 10.85 L 960.89 10.85 L 973.34 10.85 L 982.49 10.85 L 988.14 10.85 L 990.10 10.85 L 990.10 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="997.10" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="11.95" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="16.90" style="stroke: black; transform: translateX(995.05px);"></line>
 >>>> Animation with step timing function
 WebAnimation
 
-<g style="transform: translateX(0px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="673.67" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.03 10.85 L 1.41 10.85 L 5.27 10.85 L 11.49 10.85 L 19.91 10.85 L 30.42 10.85 L 42.88 10.85 L 57.15 10.85 L 73.10 10.85 L 90.59 10.85 L 109.49 10.85 L 129.66 10.85 L 150.98 10.85 L 173.30 10.85 L 196.50 10.85 L 220.43 10.85 L 244.96 10.85 L 269.97 10.85 L 295.31 10.85 L 320.84 10.85 L 346.45 10.85 L 371.98 10.85 L 397.31 10.85 L 422.31 10.85 L 446.83 10.85 L 470.75 10.85 L 493.92 10.85 L 516.22 10.85 L 537.51 10.85 L 557.66 10.85 L 576.53 10.85 L 593.99 10.85 L 609.90 10.85 L 624.13 10.85 L 636.54 10.85 L 647.00 10.85 L 655.38 10.85 L 661.54 10.85 L 665.35 10.85 L 666.67 10.85 L 666.67 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="673.67" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(666.67px);"></line>
+<g style="transform: translateX(200px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="407.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.02 10.85 L 0.85 10.85 L 3.16 10.85 L 6.89 10.85 L 11.95 10.85 L 18.25 10.85 L 25.73 10.85 L 34.29 10.85 L 43.86 10.85 L 54.35 10.85 L 65.69 10.85 L 77.80 10.85 L 90.59 10.85 L 103.98 10.85 L 117.90 10.85 L 132.26 10.85 L 146.98 10.85 L 161.98 10.85 L 177.18 10.85 L 192.51 10.85 L 207.87 10.85 L 223.19 10.85 L 238.39 10.85 L 253.39 10.85 L 268.10 10.85 L 282.45 10.85 L 296.35 10.85 L 309.73 10.85 L 322.51 10.85 L 334.60 10.85 L 345.92 10.85 L 356.39 10.85 L 365.94 10.85 L 374.48 10.85 L 381.92 10.85 L 388.20 10.85 L 393.23 10.85 L 396.92 10.85 L 399.21 10.85 L 400.00 10.85 L 400.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="407.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="207.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(600px);"></line>
+WebAnimation
+
+<g style="transform: translateX(200px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="40007.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 1.84 10.85 L 84.56 10.85 L 316.34 10.85 L 689.13 10.85 L 1194.84 10.85 L 1825.44 10.85 L 2572.84 10.85 L 3429.00 10.85 L 4385.84 10.85 L 5435.31 10.85 L 6569.34 10.85 L 7779.87 10.85 L 9058.84 10.85 L 10398.19 10.85 L 11789.84 10.85 L 13225.75 10.85 L 14697.84 10.85 L 16198.06 10.85 L 17718.34 10.85 L 19250.63 10.85 L 20786.84 10.85 L 22318.94 10.85 L 23838.84 10.85 L 25338.50 10.85 L 26809.84 10.85 L 28244.81 10.85 L 29635.34 10.85 L 30973.38 10.85 L 32250.84 10.85 L 33459.69 10.85 L 34591.84 10.85 L 35639.25 10.85 L 36593.84 10.85 L 37447.56 10.85 L 38192.34 10.85 L 38820.13 10.85 L 39322.84 10.85 L 39692.44 10.85 L 39920.84 10.85 L 40000.00 10.85 L 40000.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="40007.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="207.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="407.00" style="stroke: black; transform: translateX(1000px);"></line>
+WebAnimation
+
+<g style="transform: translateX(0px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="407.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.02 10.85 L 0.85 10.85 L 3.16 10.85 L 6.89 10.85 L 11.95 10.85 L 18.25 10.85 L 25.73 10.85 L 34.29 10.85 L 43.86 10.85 L 54.35 10.85 L 65.69 10.85 L 77.80 10.85 L 90.59 10.85 L 103.98 10.85 L 117.90 10.85 L 132.26 10.85 L 146.98 10.85 L 161.98 10.85 L 177.18 10.85 L 192.51 10.85 L 207.87 10.85 L 223.19 10.85 L 238.39 10.85 L 253.39 10.85 L 268.10 10.85 L 282.45 10.85 L 296.35 10.85 L 309.73 10.85 L 322.51 10.85 L 334.60 10.85 L 345.92 10.85 L 356.39 10.85 L 365.94 10.85 L 374.48 10.85 L 381.92 10.85 L 388.20 10.85 L 393.23 10.85 L 396.92 10.85 L 399.21 10.85 L 400.00 10.85 L 400.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="407.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(400px);"></line>
 >>>> CSS animation started
+WebAnimation
+
+<g style="transform: translateX(200px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="407.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.02 10.85 L 0.85 10.85 L 3.16 10.85 L 6.89 10.85 L 11.95 10.85 L 18.25 10.85 L 25.73 10.85 L 34.29 10.85 L 43.86 10.85 L 54.35 10.85 L 65.69 10.85 L 77.80 10.85 L 90.59 10.85 L 103.98 10.85 L 117.90 10.85 L 132.26 10.85 L 146.98 10.85 L 161.98 10.85 L 177.18 10.85 L 192.51 10.85 L 207.87 10.85 L 223.19 10.85 L 238.39 10.85 L 253.39 10.85 L 268.10 10.85 L 282.45 10.85 L 296.35 10.85 L 309.73 10.85 L 322.51 10.85 L 334.60 10.85 L 345.92 10.85 L 356.39 10.85 L 365.94 10.85 L 374.48 10.85 L 381.92 10.85 L 388.20 10.85 L 393.23 10.85 L 396.92 10.85 L 399.21 10.85 L 400.00 10.85 L 400.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="407.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="207.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(600px);"></line>
+WebAnimation
+
+<g style="transform: translateX(200px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="40007.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 1.84 10.85 L 84.56 10.85 L 316.34 10.85 L 689.13 10.85 L 1194.84 10.85 L 1825.44 10.85 L 2572.84 10.85 L 3429.00 10.85 L 4385.84 10.85 L 5435.31 10.85 L 6569.34 10.85 L 7779.87 10.85 L 9058.84 10.85 L 10398.19 10.85 L 11789.84 10.85 L 13225.75 10.85 L 14697.84 10.85 L 16198.06 10.85 L 17718.34 10.85 L 19250.63 10.85 L 20786.84 10.85 L 22318.94 10.85 L 23838.84 10.85 L 25338.50 10.85 L 26809.84 10.85 L 28244.81 10.85 L 29635.34 10.85 L 30973.38 10.85 L 32250.84 10.85 L 33459.69 10.85 L 34591.84 10.85 L 35639.25 10.85 L 36593.84 10.85 L 37447.56 10.85 L 38192.34 10.85 L 38820.13 10.85 L 39322.84 10.85 L 39692.44 10.85 L 39920.84 10.85 L 40000.00 10.85 L 40000.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="40007.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="207.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="407.00" style="stroke: black; transform: translateX(1000px);"></line>
+WebAnimation
+
+<g style="transform: translateX(0px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="407.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.02 10.85 L 0.85 10.85 L 3.16 10.85 L 6.89 10.85 L 11.95 10.85 L 18.25 10.85 L 25.73 10.85 L 34.29 10.85 L 43.86 10.85 L 54.35 10.85 L 65.69 10.85 L 77.80 10.85 L 90.59 10.85 L 103.98 10.85 L 117.90 10.85 L 132.26 10.85 L 146.98 10.85 L 161.98 10.85 L 177.18 10.85 L 192.51 10.85 L 207.87 10.85 L 223.19 10.85 L 238.39 10.85 L 253.39 10.85 L 268.10 10.85 L 282.45 10.85 L 296.35 10.85 L 309.73 10.85 L 322.51 10.85 L 334.60 10.85 L 345.92 10.85 L 356.39 10.85 L 365.94 10.85 L 374.48 10.85 L 381.92 10.85 L 388.20 10.85 L 393.23 10.85 L 396.92 10.85 L 399.21 10.85 L 400.00 10.85 L 400.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="407.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(400px);"></line>
 CSSAnimation
 anim
-<g style="transform: translateX(0px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="673.67" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.52 24.97 L 21.68 22.90 L 42.20 20.86 L 62.11 18.88 L 81.45 16.99 L 100.24 15.22 L 118.53 13.59 L 136.34 12.11 L 153.72 10.79 L 170.70 9.63 L 187.31 8.62 L 203.59 7.75 L 219.57 7.02 L 235.29 6.41 L 250.79 5.91 L 266.09 5.51 L 281.23 5.20 L 296.26 4.97 L 311.20 4.83 L 326.08 4.76 L 340.95 4.76 L 355.83 4.83 L 370.77 4.97 L 385.80 5.20 L 400.95 5.51 L 416.26 5.91 L 431.76 6.41 L 447.48 7.02 L 463.47 7.75 L 479.76 8.62 L 496.38 9.63 L 513.36 10.79 L 530.75 12.11 L 548.58 13.59 L 566.87 15.22 L 585.68 16.99 L 605.03 18.88 L 624.95 20.86 L 645.48 22.90 L 666.67 24.97 L 666.67 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="673.67" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(666.67px);"></line>
+<g style="transform: translateX(0px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="607.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.47 24.97 L 19.52 22.90 L 37.98 20.86 L 55.90 18.88 L 73.30 16.99 L 90.22 15.22 L 106.67 13.59 L 122.71 12.11 L 138.35 10.79 L 153.63 9.63 L 168.58 8.62 L 183.23 7.75 L 197.61 7.02 L 211.76 6.41 L 225.71 5.91 L 239.48 5.51 L 253.11 5.20 L 266.63 4.97 L 280.08 4.83 L 293.47 4.76 L 306.85 4.76 L 320.25 4.83 L 333.70 4.97 L 347.22 5.20 L 360.85 5.51 L 374.63 5.91 L 388.58 6.41 L 402.73 7.02 L 417.12 7.75 L 431.78 8.62 L 446.74 9.63 L 462.03 10.79 L 477.68 12.11 L 493.72 13.59 L 510.19 15.22 L 527.11 16.99 L 544.52 18.88 L 562.45 20.86 L 580.94 22.90 L 600.00 24.97 L 600.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="607.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(600px);"></line>
 >>>> CSS transition started
+WebAnimation
+
+<g style="transform: translateX(200px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="407.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.02 10.85 L 0.85 10.85 L 3.16 10.85 L 6.89 10.85 L 11.95 10.85 L 18.25 10.85 L 25.73 10.85 L 34.29 10.85 L 43.86 10.85 L 54.35 10.85 L 65.69 10.85 L 77.80 10.85 L 90.59 10.85 L 103.98 10.85 L 117.90 10.85 L 132.26 10.85 L 146.98 10.85 L 161.98 10.85 L 177.18 10.85 L 192.51 10.85 L 207.87 10.85 L 223.19 10.85 L 238.39 10.85 L 253.39 10.85 L 268.10 10.85 L 282.45 10.85 L 296.35 10.85 L 309.73 10.85 L 322.51 10.85 L 334.60 10.85 L 345.92 10.85 L 356.39 10.85 L 365.94 10.85 L 374.48 10.85 L 381.92 10.85 L 388.20 10.85 L 393.23 10.85 L 396.92 10.85 L 399.21 10.85 L 400.00 10.85 L 400.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="407.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="207.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(600px);"></line>
+WebAnimation
+
+<g style="transform: translateX(200px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="40007.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 1.84 10.85 L 84.56 10.85 L 316.34 10.85 L 689.13 10.85 L 1194.84 10.85 L 1825.44 10.85 L 2572.84 10.85 L 3429.00 10.85 L 4385.84 10.85 L 5435.31 10.85 L 6569.34 10.85 L 7779.87 10.85 L 9058.84 10.85 L 10398.19 10.85 L 11789.84 10.85 L 13225.75 10.85 L 14697.84 10.85 L 16198.06 10.85 L 17718.34 10.85 L 19250.63 10.85 L 20786.84 10.85 L 22318.94 10.85 L 23838.84 10.85 L 25338.50 10.85 L 26809.84 10.85 L 28244.81 10.85 L 29635.34 10.85 L 30973.38 10.85 L 32250.84 10.85 L 33459.69 10.85 L 34591.84 10.85 L 35639.25 10.85 L 36593.84 10.85 L 37447.56 10.85 L 38192.34 10.85 L 38820.13 10.85 L 39322.84 10.85 L 39692.44 10.85 L 39920.84 10.85 L 40000.00 10.85 L 40000.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="40007.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="207.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="407.00" style="stroke: black; transform: translateX(1000px);"></line>
+WebAnimation
+
+<g style="transform: translateX(0px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="407.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.02 10.85 L 0.85 10.85 L 3.16 10.85 L 6.89 10.85 L 11.95 10.85 L 18.25 10.85 L 25.73 10.85 L 34.29 10.85 L 43.86 10.85 L 54.35 10.85 L 65.69 10.85 L 77.80 10.85 L 90.59 10.85 L 103.98 10.85 L 117.90 10.85 L 132.26 10.85 L 146.98 10.85 L 161.98 10.85 L 177.18 10.85 L 192.51 10.85 L 207.87 10.85 L 223.19 10.85 L 238.39 10.85 L 253.39 10.85 L 268.10 10.85 L 282.45 10.85 L 296.35 10.85 L 309.73 10.85 L 322.51 10.85 L 334.60 10.85 L 345.92 10.85 L 356.39 10.85 L 365.94 10.85 L 374.48 10.85 L 381.92 10.85 L 388.20 10.85 L 393.23 10.85 L 396.92 10.85 L 399.21 10.85 L 400.00 10.85 L 400.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="407.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(400px);"></line>
+CSSAnimation
+anim
+<g style="transform: translateX(0px);"><g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="607.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.47 24.97 L 19.52 22.90 L 37.98 20.86 L 55.90 18.88 L 73.30 16.99 L 90.22 15.22 L 106.67 13.59 L 122.71 12.11 L 138.35 10.79 L 153.63 9.63 L 168.58 8.62 L 183.23 7.75 L 197.61 7.02 L 211.76 6.41 L 225.71 5.91 L 239.48 5.51 L 253.11 5.20 L 266.63 4.97 L 280.08 4.83 L 293.47 4.76 L 306.85 4.76 L 320.25 4.83 L 333.70 4.97 L 347.22 5.20 L 360.85 5.51 L 374.63 5.91 L 388.58 6.41 L 402.73 7.02 L 417.12 7.75 L 431.78 8.62 L 446.74 9.63 L 462.03 10.79 L 477.68 12.11 L 493.72 13.59 L 510.19 15.22 L 527.11 16.99 L 544.52 18.88 L 562.45 20.86 L 580.94 22.90 L 600.00 24.97 L 600.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="607.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><g class="animation-tail-iterations"></g></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(600px);"></line>
 CSSTransition
 background-color
-<g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="673.67" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.02 0.00 L 0.71 0.00 L 2.69 0.00 L 5.90 0.02 L 10.33 0.11 L 15.93 0.31 L 22.68 0.66 L 30.54 1.15 L 39.47 1.76 L 49.44 2.45 L 60.43 3.21 L 72.38 4.00 L 85.28 4.82 L 99.09 5.64 L 113.77 6.47 L 129.29 7.29 L 145.62 8.10 L 162.73 8.90 L 180.57 9.69 L 199.12 10.46 L 218.34 11.23 L 238.20 11.98 L 258.66 12.72 L 279.70 13.46 L 301.28 14.19 L 323.36 14.91 L 345.91 15.63 L 368.90 16.35 L 392.29 17.08 L 416.06 17.80 L 440.16 18.53 L 464.56 19.26 L 489.23 20.01 L 514.14 20.76 L 539.25 21.52 L 564.53 22.30 L 589.95 23.09 L 615.46 23.90 L 641.05 24.72 L 666.67 25.57 L 666.67 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="673.67" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(666.67px);"></line>
+<g style="transform: translateX(0px);"><line class="animation-line" x1="7" y1="26" y2="26" x2="307.00" style="stroke: black;"></line><path class="animation-keyframe" d="M 0 26 L 0.01 0.00 L 0.32 0.00 L 1.21 0.00 L 2.66 0.02 L 4.65 0.11 L 7.17 0.31 L 10.21 0.66 L 13.74 1.15 L 17.76 1.76 L 22.25 2.45 L 27.19 3.21 L 32.57 4.00 L 38.38 4.82 L 44.59 5.64 L 51.20 6.47 L 58.18 7.29 L 65.53 8.10 L 73.23 8.90 L 81.26 9.69 L 89.60 10.46 L 98.25 11.23 L 107.19 11.98 L 116.40 12.72 L 125.87 13.46 L 135.58 14.19 L 145.51 14.91 L 155.66 15.63 L 166.00 16.35 L 176.53 17.08 L 187.23 17.80 L 198.07 18.53 L 209.05 19.26 L 220.15 20.01 L 231.36 20.76 L 242.66 21.52 L 254.04 22.30 L 265.48 23.09 L 276.96 23.90 L 288.47 24.72 L 300.00 25.57 L 300.00 26 Z" style="transform: translateX(7px); fill: black;"></path><circle class="animation-endpoint" cx="7.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle><circle class="animation-endpoint" cx="307.00" cy="26" r="3.5" style="stroke: black; fill: black;"></circle></g><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black;"></line><line class="animation-delay-line" x1="7" y1="26" y2="26" x2="7.00" style="stroke: black; transform: translateX(300px);"></line>
 
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-001-expected.png b/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-001-expected.png
deleted file mode 100644
index 2484a83..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-001-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-001-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-001-expected.txt
deleted file mode 100644
index 2f7b355..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-001-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (0,0) size 784x210 [border: (2px solid #0000FF)]
-        LayoutBlockFlow {DIV} at (14,14) size 756x55
-          LayoutText {#text} at (0,0) size 64x26
-            text run at (0,0) width 64: "Tests: "
-          LayoutBR {BR} at (0,0) size 0x0
-          LayoutText {#text} at (0,27) size 489x27
-            text run at (0,27) width 489: "Smart delete when deleting the first word on a line."
-        LayoutBlockFlow {DIV} at (14,85) size 756x111
-          LayoutText {#text} at (0,0) size 189x26
-            text run at (0,0) width 189: "Expected Results: "
-          LayoutBR {BR} at (189,21) size 0x0
-          LayoutText {#text} at (0,27) size 705x55
-            text run at (0,27) width 705: "The first word and the space following the first word should be deleted. It"
-            text run at (0,55) width 196: "should like this this: "
-          LayoutBR {BR} at (196,76) size 0x0
-          LayoutText {#text} at (0,83) size 70x27
-            text run at (0,83) width 70: "bar baz"
-      LayoutBlockFlow {DIV} at (0,234) size 784x32
-        LayoutBlockFlow {DIV} at (0,0) size 784x32 [border: (2px solid #FF0000)]
-          LayoutText {#text} at (2,2) size 70x27
-            text run at (2,2) width 70: "bar baz"
-caret: position 0 of child 0 {#text} of child 1 {DIV} of child 3 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-002-expected.png b/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-002-expected.png
deleted file mode 100644
index 51987bf5..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-002-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-002-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-002-expected.txt
deleted file mode 100644
index fd16889a..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/smart-delete-002-expected.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (0,0) size 784x210 [border: (2px solid #0000FF)]
-        LayoutBlockFlow {DIV} at (14,14) size 756x55
-          LayoutText {#text} at (0,0) size 64x26
-            text run at (0,0) width 64: "Tests: "
-          LayoutBR {BR} at (0,0) size 0x0
-          LayoutText {#text} at (0,27) size 514x27
-            text run at (0,27) width 514: "Smart delete when deleting the second word of a line."
-        LayoutBlockFlow {DIV} at (14,85) size 756x111
-          LayoutText {#text} at (0,0) size 189x26
-            text run at (0,0) width 189: "Expected Results: "
-          LayoutBR {BR} at (189,21) size 0x0
-          LayoutText {#text} at (0,27) size 735x55
-            text run at (0,27) width 735: "The second word and the space before the second word should be deleted. It"
-            text run at (0,55) width 196: "should like this this: "
-          LayoutBR {BR} at (196,76) size 0x0
-          LayoutText {#text} at (0,83) size 71x27
-            text run at (0,83) width 71: "foo baz"
-      LayoutBlockFlow {DIV} at (0,234) size 784x32
-        LayoutBlockFlow {DIV} at (0,0) size 784x32 [border: (2px solid #FF0000)]
-          LayoutText {#text} at (2,2) size 71x27
-            text run at (2,2) width 71: "foo baz"
-caret: position 4 of child 0 {#text} of child 1 {DIV} of child 3 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-001-expected.png
deleted file mode 100644
index ca2bb3a..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-001-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-001-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-001-expected.txt
deleted file mode 100644
index c014053..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-001-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (0,0) size 784x212 [border: (2px solid #0000FF)]
-        LayoutBlockFlow {DIV} at (14,14) size 756x56
-          LayoutText {#text} at (0,0) size 66x28
-            text run at (0,0) width 66: "Tests: "
-          LayoutBR {BR} at (0,0) size 0x0
-          LayoutText {#text} at (0,28) size 491x28
-            text run at (0,28) width 491: "Smart delete when deleting the first word on a line."
-        LayoutBlockFlow {DIV} at (14,86) size 756x112
-          LayoutText {#text} at (0,0) size 190x28
-            text run at (0,0) width 190: "Expected Results: "
-          LayoutBR {BR} at (189,22) size 1x0
-          LayoutText {#text} at (0,28) size 706x56
-            text run at (0,28) width 706: "The first word and the space following the first word should be deleted. It"
-            text run at (0,56) width 201: "should like this this: "
-          LayoutBR {BR} at (200,78) size 1x0
-          LayoutText {#text} at (0,84) size 70x28
-            text run at (0,84) width 70: "bar baz"
-      LayoutBlockFlow {DIV} at (0,236) size 784x32
-        LayoutBlockFlow {DIV} at (0,0) size 784x32 [border: (2px solid #FF0000)]
-          LayoutText {#text} at (2,2) size 70x28
-            text run at (2,2) width 70: "bar baz"
-caret: position 0 of child 0 {#text} of child 1 {DIV} of child 3 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-002-expected.png
deleted file mode 100644
index d812b8a..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-002-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-002-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-002-expected.txt
deleted file mode 100644
index 79054d9a..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/smart-delete-002-expected.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (0,0) size 784x212 [border: (2px solid #0000FF)]
-        LayoutBlockFlow {DIV} at (14,14) size 756x56
-          LayoutText {#text} at (0,0) size 66x28
-            text run at (0,0) width 66: "Tests: "
-          LayoutBR {BR} at (0,0) size 0x0
-          LayoutText {#text} at (0,28) size 516x28
-            text run at (0,28) width 516: "Smart delete when deleting the second word of a line."
-        LayoutBlockFlow {DIV} at (14,86) size 756x112
-          LayoutText {#text} at (0,0) size 190x28
-            text run at (0,0) width 190: "Expected Results: "
-          LayoutBR {BR} at (189,22) size 1x0
-          LayoutText {#text} at (0,28) size 732x56
-            text run at (0,28) width 732: "The second word and the space before the second word should be deleted. It"
-            text run at (0,56) width 201: "should like this this: "
-          LayoutBR {BR} at (200,78) size 1x0
-          LayoutText {#text} at (0,84) size 72x28
-            text run at (0,84) width 72: "foo baz"
-      LayoutBlockFlow {DIV} at (0,236) size 784x32
-        LayoutBlockFlow {DIV} at (0,0) size 784x32 [border: (2px solid #FF0000)]
-          LayoutText {#text} at (2,2) size 72x28
-            text run at (2,2) width 72: "foo baz"
-caret: position 4 of child 0 {#text} of child 1 {DIV} of child 3 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-001-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-001-expected.png
deleted file mode 100644
index a7cc9a56f..0000000
--- a/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-001-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-001-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-001-expected.txt
deleted file mode 100644
index c5d5216..0000000
--- a/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-001-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (0,0) size 784x210 [border: (2px solid #0000FF)]
-        LayoutBlockFlow {DIV} at (14,14) size 756x55
-          LayoutText {#text} at (0,0) size 66x26
-            text run at (0,0) width 66: "Tests: "
-          LayoutBR {BR} at (0,0) size 0x0
-          LayoutText {#text} at (0,27) size 489x27
-            text run at (0,27) width 489: "Smart delete when deleting the first word on a line."
-        LayoutBlockFlow {DIV} at (14,85) size 756x111
-          LayoutText {#text} at (0,0) size 189x26
-            text run at (0,0) width 189: "Expected Results: "
-          LayoutBR {BR} at (189,21) size 0x0
-          LayoutText {#text} at (0,27) size 705x55
-            text run at (0,27) width 705: "The first word and the space following the first word should be deleted. It"
-            text run at (0,55) width 196: "should like this this: "
-          LayoutBR {BR} at (196,76) size 0x0
-          LayoutText {#text} at (0,83) size 70x27
-            text run at (0,83) width 70: "bar baz"
-      LayoutBlockFlow {DIV} at (0,234) size 784x32
-        LayoutBlockFlow {DIV} at (0,0) size 784x32 [border: (2px solid #FF0000)]
-          LayoutText {#text} at (2,2) size 70x27
-            text run at (2,2) width 70: "bar baz"
-caret: position 0 of child 0 {#text} of child 1 {DIV} of child 3 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-002-expected.png b/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-002-expected.png
deleted file mode 100644
index e0c9fce..0000000
--- a/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-002-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-002-expected.txt b/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-002-expected.txt
deleted file mode 100644
index a2842f0e..0000000
--- a/third_party/WebKit/LayoutTests/platform/win-xp/editing/deleting/smart-delete-002-expected.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (0,0) size 784x210 [border: (2px solid #0000FF)]
-        LayoutBlockFlow {DIV} at (14,14) size 756x55
-          LayoutText {#text} at (0,0) size 66x26
-            text run at (0,0) width 66: "Tests: "
-          LayoutBR {BR} at (0,0) size 0x0
-          LayoutText {#text} at (0,27) size 514x27
-            text run at (0,27) width 514: "Smart delete when deleting the second word of a line."
-        LayoutBlockFlow {DIV} at (14,85) size 756x111
-          LayoutText {#text} at (0,0) size 189x26
-            text run at (0,0) width 189: "Expected Results: "
-          LayoutBR {BR} at (189,21) size 0x0
-          LayoutText {#text} at (0,27) size 735x55
-            text run at (0,27) width 735: "The second word and the space before the second word should be deleted. It"
-            text run at (0,55) width 196: "should like this this: "
-          LayoutBR {BR} at (196,76) size 0x0
-          LayoutText {#text} at (0,83) size 71x27
-            text run at (0,83) width 71: "foo baz"
-      LayoutBlockFlow {DIV} at (0,234) size 784x32
-        LayoutBlockFlow {DIV} at (0,0) size 784x32 [border: (2px solid #FF0000)]
-          LayoutText {#text} at (2,2) size 71x27
-            text run at (2,2) width 71: "foo baz"
-caret: position 5 of child 0 {#text} of child 1 {DIV} of child 3 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-001-expected.png b/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-001-expected.png
deleted file mode 100644
index 1f1f53e..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-001-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-001-expected.txt b/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-001-expected.txt
deleted file mode 100644
index 4ec15cf..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-001-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (0,0) size 784x206 [border: (2px solid #0000FF)]
-        LayoutBlockFlow {DIV} at (14,14) size 756x54
-          LayoutText {#text} at (0,0) size 66x26
-            text run at (0,0) width 66: "Tests: "
-          LayoutBR {BR} at (0,0) size 0x0
-          LayoutText {#text} at (0,27) size 492x26
-            text run at (0,27) width 492: "Smart delete when deleting the first word on a line."
-        LayoutBlockFlow {DIV} at (14,84) size 756x108
-          LayoutText {#text} at (0,0) size 190x26
-            text run at (0,0) width 190: "Expected Results: "
-          LayoutBR {BR} at (189,21) size 1x0
-          LayoutText {#text} at (0,27) size 708x53
-            text run at (0,27) width 708: "The first word and the space following the first word should be deleted. It"
-            text run at (0,54) width 201: "should like this this: "
-          LayoutBR {BR} at (200,75) size 1x0
-          LayoutText {#text} at (0,81) size 70x26
-            text run at (0,81) width 70: "bar baz"
-      LayoutBlockFlow {DIV} at (0,230) size 784x31
-        LayoutBlockFlow {DIV} at (0,0) size 784x31 [border: (2px solid #FF0000)]
-          LayoutText {#text} at (2,2) size 70x26
-            text run at (2,2) width 70: "bar baz"
-caret: position 0 of child 0 {#text} of child 1 {DIV} of child 3 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-002-expected.png b/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-002-expected.png
deleted file mode 100644
index 263cd867..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-002-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-002-expected.txt b/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-002-expected.txt
deleted file mode 100644
index e80bd68..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/smart-delete-002-expected.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {DIV} at (0,0) size 784x206 [border: (2px solid #0000FF)]
-        LayoutBlockFlow {DIV} at (14,14) size 756x54
-          LayoutText {#text} at (0,0) size 66x26
-            text run at (0,0) width 66: "Tests: "
-          LayoutBR {BR} at (0,0) size 0x0
-          LayoutText {#text} at (0,27) size 516x26
-            text run at (0,27) width 516: "Smart delete when deleting the second word of a line."
-        LayoutBlockFlow {DIV} at (14,84) size 756x108
-          LayoutText {#text} at (0,0) size 190x26
-            text run at (0,0) width 190: "Expected Results: "
-          LayoutBR {BR} at (189,21) size 1x0
-          LayoutText {#text} at (0,27) size 732x53
-            text run at (0,27) width 732: "The second word and the space before the second word should be deleted. It"
-            text run at (0,54) width 201: "should like this this: "
-          LayoutBR {BR} at (200,75) size 1x0
-          LayoutText {#text} at (0,81) size 72x26
-            text run at (0,81) width 72: "foo baz"
-      LayoutBlockFlow {DIV} at (0,230) size 784x31
-        LayoutBlockFlow {DIV} at (0,0) size 784x31 [border: (2px solid #FF0000)]
-          LayoutText {#text} at (2,2) size 72x26
-            text run at (2,2) width 72: "foo baz"
-caret: position 5 of child 0 {#text} of child 1 {DIV} of child 3 {DIV} of body
diff --git a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
index 3d44613..81f6967 100644
--- a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
+++ b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.txt
@@ -36,7 +36,7 @@
 ActiveDOMObject
 CachedAttribute=*
 CallWith=ExecutionContext|ScriptState|ScriptArguments|ActiveWindow|FirstWindow|ThisValue
-CheckSecurity=Frame|Node|Window
+CheckSecurity=Receiver|ReturnValue
 Clamp
 Conditional=*
 Constructor
diff --git a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp
index 9654ddf..bbbace5b 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.cpp
@@ -41,13 +41,15 @@
 
 namespace blink {
 
-static bool isOriginAccessibleFromDOMWindow(SecurityOrigin* targetOrigin, LocalDOMWindow* accessingWindow)
+static bool isOriginAccessibleFromDOMWindow(const SecurityOrigin* targetOrigin, const LocalDOMWindow* accessingWindow)
 {
     return accessingWindow && accessingWindow->document()->securityOrigin()->canAccessCheckSuborigins(targetOrigin);
 }
 
-static bool canAccessFrame(v8::Isolate* isolate, LocalDOMWindow* accessingWindow, SecurityOrigin* targetFrameOrigin, DOMWindow* targetWindow, ExceptionState& exceptionState)
+static bool canAccessFrame(v8::Isolate* isolate, const LocalDOMWindow* accessingWindow, const SecurityOrigin* targetFrameOrigin, const DOMWindow* targetWindow, ExceptionState& exceptionState)
 {
+    ASSERT_WITH_SECURITY_IMPLICATION(!(targetWindow && targetWindow->frame()) || targetWindow == targetWindow->frame()->domWindow());
+
     if (isOriginAccessibleFromDOMWindow(targetFrameOrigin, accessingWindow))
         return true;
 
@@ -56,8 +58,10 @@
     return false;
 }
 
-static bool canAccessFrame(v8::Isolate* isolate, LocalDOMWindow* accessingWindow, SecurityOrigin* targetFrameOrigin, DOMWindow* targetWindow, SecurityReportingOption reportingOption = ReportSecurityError)
+static bool canAccessFrame(v8::Isolate* isolate, const LocalDOMWindow* accessingWindow, SecurityOrigin* targetFrameOrigin, const DOMWindow* targetWindow, SecurityReportingOption reportingOption = ReportSecurityError)
 {
+    ASSERT_WITH_SECURITY_IMPLICATION(!(targetWindow && targetWindow->frame()) || targetWindow == targetWindow->frame()->domWindow());
+
     if (isOriginAccessibleFromDOMWindow(targetFrameOrigin, accessingWindow))
         return true;
 
@@ -66,28 +70,77 @@
     return false;
 }
 
-bool BindingSecurity::shouldAllowAccessToFrame(v8::Isolate* isolate, LocalDOMWindow* accessingWindow, Frame* target, SecurityReportingOption reportingOption)
+bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWindow* accessingWindow, const DOMWindow* target, ExceptionState& exceptionState)
+{
+    ASSERT(target);
+    const Frame* frame = target->frame();
+    if (!frame || !frame->securityContext())
+        return false;
+    return canAccessFrame(isolate, accessingWindow, frame->securityContext()->securityOrigin(), target, exceptionState);
+}
+
+bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWindow* accessingWindow, const DOMWindow* target, SecurityReportingOption reportingOption)
+{
+    ASSERT(target);
+    const Frame* frame = target->frame();
+    if (!frame || !frame->securityContext())
+        return false;
+    return canAccessFrame(isolate, accessingWindow, frame->securityContext()->securityOrigin(), target, reportingOption);
+}
+
+bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWindow* accessingWindow, const EventTarget* target, ExceptionState& exceptionState)
+{
+    ASSERT(target);
+    const DOMWindow* window = target->toDOMWindow();
+    if (!window) {
+        // We only need to check the access to Window objects which are
+        // cross-origin accessible.  If it's not a Window, the object's
+        // origin must always be the same origin (or it already leaked).
+        return true;
+    }
+    const Frame* frame = window->frame();
+    if (!frame || !frame->securityContext())
+        return false;
+    return canAccessFrame(isolate, accessingWindow, frame->securityContext()->securityOrigin(), window, exceptionState);
+}
+
+bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWindow* accessingWindow, const Location* target, ExceptionState& exceptionState)
+{
+    ASSERT(target);
+    const Frame* frame = target->frame();
+    if (!frame || !frame->securityContext())
+        return false;
+    return canAccessFrame(isolate, accessingWindow, frame->securityContext()->securityOrigin(), frame->domWindow(), exceptionState);
+}
+
+bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWindow* accessingWindow, const Location* target, SecurityReportingOption reportingOption)
+{
+    ASSERT(target);
+    const Frame* frame = target->frame();
+    if (!frame || !frame->securityContext())
+        return false;
+    return canAccessFrame(isolate, accessingWindow, frame->securityContext()->securityOrigin(), frame->domWindow(), reportingOption);
+}
+
+bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWindow* accessingWindow, const Node* target, ExceptionState& exceptionState)
+{
+    if (!target)
+        return false;
+    return canAccessFrame(isolate, accessingWindow, target->document().securityOrigin(), target->document().domWindow(), exceptionState);
+}
+
+bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWindow* accessingWindow, const Node* target, SecurityReportingOption reportingOption)
+{
+    if (!target)
+        return false;
+    return canAccessFrame(isolate, accessingWindow, target->document().securityOrigin(), target->document().domWindow(), reportingOption);
+}
+
+bool BindingSecurity::shouldAllowAccessToFrame(v8::Isolate* isolate, const LocalDOMWindow* accessingWindow, const Frame* target, SecurityReportingOption reportingOption)
 {
     if (!target || !target->securityContext())
         return false;
     return canAccessFrame(isolate, accessingWindow, target->securityContext()->securityOrigin(), target->domWindow(), reportingOption);
 }
 
-bool BindingSecurity::shouldAllowAccessToFrame(v8::Isolate* isolate, LocalDOMWindow* accessingWindow, Frame* target, ExceptionState& exceptionState)
-{
-    if (!target || !target->securityContext())
-        return false;
-    return canAccessFrame(isolate, accessingWindow, target->securityContext()->securityOrigin(), target->domWindow(), exceptionState);
-}
-
-bool BindingSecurity::shouldAllowAccessToNode(v8::Isolate* isolate, LocalDOMWindow* accessingWindow, Node* target, SecurityReportingOption reportingOption)
-{
-    return target && canAccessFrame(isolate, accessingWindow, target->document().securityOrigin(), target->document().domWindow(), reportingOption);
-}
-
-bool BindingSecurity::shouldAllowAccessToNode(v8::Isolate* isolate, LocalDOMWindow* accessingWindow, Node* target, ExceptionState& exceptionState)
-{
-    return target && canAccessFrame(isolate, accessingWindow, target->document().securityOrigin(), target->document().domWindow(), exceptionState);
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.h b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.h
index f8fbe35..85205f6 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.h
+++ b/third_party/WebKit/Source/bindings/core/v8/BindingSecurity.h
@@ -31,16 +31,18 @@
 #ifndef BindingSecurity_h
 #define BindingSecurity_h
 
-// FIXME: The LocalFrame include should not be necessary, clients should be including it where they use it.
 #include "core/CoreExport.h"
-#include "core/frame/LocalFrame.h"
 #include "wtf/Allocator.h"
 #include <v8.h>
 
 namespace blink {
 
-class LocalDOMWindow;
+class DOMWindow;
+class EventTarget;
 class ExceptionState;
+class Frame;
+class LocalDOMWindow;
+class Location;
 class Node;
 
 enum SecurityReportingOption {
@@ -48,18 +50,45 @@
     ReportSecurityError,
 };
 
-class BindingSecurity {
+class CORE_EXPORT BindingSecurity {
     STATIC_ONLY(BindingSecurity);
 public:
-    // Check the access to the return value.
-    static bool shouldAllowAccessToNode(v8::Isolate*, LocalDOMWindow* accessingWindow, Node*, SecurityReportingOption);
-    static bool shouldAllowAccessToNode(v8::Isolate*, LocalDOMWindow* accessingWindow, Node*, ExceptionState&);
+    // Check if the caller (|accessingWindow|) is allowed to access the JS
+    // receiver object (|target|), where the receiver object is the JS object
+    // for which the DOM attribute or DOM operation is being invoked (in the
+    // form of receiver.domAttr or receiver.domOp()).
+    // Note that only Window and Location objects are cross-origin accessible
+    // and that EventTarget interface is the parent interface of Window
+    // interface.  So the receiver object must be of type DOMWindow,
+    // EventTarget, or Location.
+    //
+    // DOMWindow
+    static bool shouldAllowAccessTo(v8::Isolate*, const LocalDOMWindow* accessingWindow, const DOMWindow* target, ExceptionState&);
+    static bool shouldAllowAccessTo(v8::Isolate*, const LocalDOMWindow* accessingWindow, const DOMWindow* target, SecurityReportingOption);
+    // EventTarget (as the parent of DOMWindow)
+    static bool shouldAllowAccessTo(v8::Isolate*, const LocalDOMWindow* accessingWindow, const EventTarget* target, ExceptionState&);  // NOLINT(readability/parameter_name)
+    // Location
+    static bool shouldAllowAccessTo(v8::Isolate*, const LocalDOMWindow* accessingWindow, const Location* target, ExceptionState&);
+    static bool shouldAllowAccessTo(v8::Isolate*, const LocalDOMWindow* accessingWindow, const Location* target, SecurityReportingOption);
+    // Prefer to use the previous overloads instead of falling back to using
+    // Frame*.
+    static bool shouldAllowAccessToFrame(v8::Isolate*, const LocalDOMWindow* accessingWindow, const Frame* target, SecurityReportingOption); // OBSOLETE
 
-    // Check the access to the receiver.
-    CORE_EXPORT static bool shouldAllowAccessToFrame(v8::Isolate*, LocalDOMWindow* accessingWindow, Frame*, SecurityReportingOption = ReportSecurityError);
-    CORE_EXPORT static bool shouldAllowAccessToFrame(v8::Isolate*, LocalDOMWindow* accessingWindow, Frame*, ExceptionState&);
+    // Check if the caller (|accessingWindow|) is allowed to access the JS
+    // returned object (|target|), where the returned object is the JS object
+    // which is returned as a result of invoking a DOM attribute or DOM
+    // operation (in the form of
+    //   var x = receiver.domAttr // or receiver.domOp()
+    // where |x| is the returned object).
+    // See window.frameElement for example, which may return a frame object.
+    // The object returned from window.frameElement must be the same origin if
+    // it's not null.
+    //
+    // Node
+    static bool shouldAllowAccessTo(v8::Isolate*, const LocalDOMWindow* accessingWindow, const Node* target, ExceptionState&);
+    static bool shouldAllowAccessTo(v8::Isolate*, const LocalDOMWindow* accessingWindow, const Node* target, SecurityReportingOption);
 };
 
-}
+} // namespace blink
 
 #endif
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
index 4a354bc7..c39597d 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
@@ -89,7 +89,7 @@
     if (!frame)
         return false;
     v8::Isolate* isolate = toIsolate(frame);
-    return !isolate->InContext() || BindingSecurity::shouldAllowAccessToFrame(isolate, callingDOMWindow(isolate), frame);
+    return !isolate->InContext() || BindingSecurity::shouldAllowAccessToFrame(isolate, callingDOMWindow(isolate), frame, ReportSecurityError);
 }
 
 ScriptController::ScriptController(LocalFrame* frame)
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8EventTargetCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8EventTargetCustom.cpp
index 58528e58..2f0b950 100644
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8EventTargetCustom.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8EventTargetCustom.cpp
@@ -78,13 +78,9 @@
         return;
     }
     EventTarget* impl = V8EventTarget::toImpl(info.Holder());
-    if (LocalDOMWindow* window = impl->toDOMWindow()) {
-        if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), window->frame(), exceptionState)) {
-            exceptionState.throwIfNeeded();
-            return;
-        }
-        if (!window->document())
-            return;
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
+        exceptionState.throwIfNeeded();
+        return;
     }
     V8StringResource<> type;
     RefPtrWillBeRawPtr<EventListener> listener;
@@ -121,13 +117,9 @@
         return;
     }
     EventTarget* impl = V8EventTarget::toImpl(info.Holder());
-    if (LocalDOMWindow* window = impl->toDOMWindow()) {
-        if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), window->frame(), exceptionState)) {
-            exceptionState.throwIfNeeded();
-            return;
-        }
-        if (!window->document())
-            return;
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
+        exceptionState.throwIfNeeded();
+        return;
     }
     V8StringResource<> type;
     RefPtrWillBeRawPtr<EventListener> listener;
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8InjectedScriptManager.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8InjectedScriptManager.cpp
index c5d2934f..bb56576 100644
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8InjectedScriptManager.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8InjectedScriptManager.cpp
@@ -83,15 +83,8 @@
     if (!scriptState->contextIsValid())
         return false;
     ScriptState::Scope scope(scriptState);
-    v8::Local<v8::Object> global = scriptState->context()->Global();
-    if (global.IsEmpty())
-        return false;
-    v8::Local<v8::Object> holder = V8Window::findInstanceInPrototypeChain(global, scriptState->isolate());
-    if (holder.IsEmpty())
-        return false;
-    LocalFrame* frame = toLocalDOMWindow(V8Window::toImpl(holder))->frame();
-
-    return BindingSecurity::shouldAllowAccessToFrame(scriptState->isolate(), callingDOMWindow(scriptState->isolate()), frame, DoNotReportSecurityError);
+    DOMWindow* window = toDOMWindow(scriptState->isolate(), scriptState->context()->Global());
+    return window && BindingSecurity::shouldAllowAccessTo(scriptState->isolate(), callingDOMWindow(scriptState->isolate()), window, DoNotReportSecurityError);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp
index d6a5292..794d2672 100644
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8WindowCustom.cpp
@@ -68,13 +68,14 @@
 
 void V8Window::eventAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info)
 {
-    LocalFrame* frame = toLocalDOMWindow(V8Window::toImpl(info.Holder()))->frame();
+    LocalDOMWindow* impl = toLocalDOMWindow(V8Window::toImpl(info.Holder()));
     ExceptionState exceptionState(ExceptionState::GetterContext, "event", "Window", info.Holder(), info.GetIsolate());
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), frame, exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         exceptionState.throwIfNeeded();
         return;
     }
 
+    LocalFrame* frame = impl->frame();
     ASSERT(frame);
     // This is a fast path to retrieve info.Holder()->CreationContext().
     v8::Local<v8::Context> context = toV8Context(frame, DOMWrapperWorld::current(info.GetIsolate()));
@@ -89,13 +90,14 @@
 
 void V8Window::eventAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
 {
-    LocalFrame* frame = toLocalDOMWindow(V8Window::toImpl(info.Holder()))->frame();
+    LocalDOMWindow* impl = toLocalDOMWindow(V8Window::toImpl(info.Holder()));
     ExceptionState exceptionState(ExceptionState::SetterContext, "event", "Window", info.Holder(), info.GetIsolate());
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), frame, exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         exceptionState.throwIfNeeded();
         return;
     }
 
+    LocalFrame* frame = impl->frame();
     ASSERT(frame);
     // This is a fast path to retrieve info.Holder()->CreationContext().
     v8::Local<v8::Context> context = toV8Context(frame, DOMWrapperWorld::current(info.GetIsolate()));
@@ -109,7 +111,7 @@
 {
     LocalDOMWindow* impl = toLocalDOMWindow(V8Window::toImpl(info.Holder()));
 
-    if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frameElement(), DoNotReportSecurityError)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frameElement(), DoNotReportSecurityError)) {
         v8SetReturnValueNull(info);
         return;
     }
@@ -127,7 +129,7 @@
     v8::Isolate* isolate = info.GetIsolate();
     DOMWindow* impl = V8Window::toImpl(info.Holder());
     ExceptionState exceptionState(ExceptionState::SetterContext, "opener", "Window", info.Holder(), isolate);
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         exceptionState.throwIfNeeded();
         return;
     }
@@ -233,7 +235,7 @@
 {
     DOMWindow* impl = V8Window::toImpl(info.Holder());
     ExceptionState exceptionState(ExceptionState::ExecutionContext, "open", "Window", info.Holder(), info.GetIsolate());
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         exceptionState.throwIfNeeded();
         return;
     }
@@ -330,7 +332,7 @@
         return;
 
     // This is an AllCanRead interceptor.  Check that the caller has access to the named results.
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), frame, DoNotReportSecurityError))
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), window, DoNotReportSecurityError))
         return;
 
     bool hasNamedItem = toHTMLDocument(doc)->hasNamedItem(propName);
@@ -378,7 +380,7 @@
     if (target->loader().stateMachine()->isDisplayingInitialEmptyDocument())
         target->loader().didAccessInitialDocument();
 
-    return BindingSecurity::shouldAllowAccessToFrame(isolate, callingDOMWindow(isolate), target, DoNotReportSecurityError);
+    return BindingSecurity::shouldAllowAccessTo(isolate, callingDOMWindow(isolate), targetWindow, DoNotReportSecurityError);
 }
 
 bool V8Window::securityCheckCustom(v8::Local<v8::Context> accessingContext, v8::Local<v8::Object> accessedObject)
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_attributes.py b/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
index 850fb54b..6535851 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_attributes.py
@@ -55,15 +55,12 @@
 
     # [CheckSecurity]
     is_do_not_check_security = 'DoNotCheckSecurity' in extended_attributes
-    is_check_security_for_frame = (
-        has_extended_attribute_value(interface, 'CheckSecurity', 'Frame') and
+    is_check_security_for_receiver = (
+        has_extended_attribute_value(interface, 'CheckSecurity', 'Receiver') and
         not is_do_not_check_security)
-    is_check_security_for_node = (
-        has_extended_attribute_value(attribute, 'CheckSecurity', 'Node'))
-    is_check_security_for_window = (
-        has_extended_attribute_value(interface, 'CheckSecurity', 'Window') and
-        not is_do_not_check_security)
-    if is_check_security_for_frame or is_check_security_for_node or is_check_security_for_window:
+    is_check_security_for_return_value = (
+        has_extended_attribute_value(attribute, 'CheckSecurity', 'ReturnValue'))
+    if is_check_security_for_receiver or is_check_security_for_return_value:
         includes.add('bindings/core/v8/BindingSecurity.h')
     # [Constructor]
     # TODO(yukishiino): Constructors are much like methods although constructors
@@ -119,9 +116,8 @@
         'idl_type': str(idl_type),  # need trailing [] on array for Dictionary::ConversionContext::setConversionType
         'is_call_with_execution_context': has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'),
         'is_call_with_script_state': has_extended_attribute_value(attribute, 'CallWith', 'ScriptState'),
-        'is_check_security_for_frame': is_check_security_for_frame,
-        'is_check_security_for_node': is_check_security_for_node,
-        'is_check_security_for_window': is_check_security_for_window,
+        'is_check_security_for_receiver': is_check_security_for_receiver,
+        'is_check_security_for_return_value': is_check_security_for_return_value,
         'is_custom_element_callbacks': is_custom_element_callbacks,
         # TODO(yukishiino): Make all DOM attributes accessor-type properties.
         'is_data_type_property': constructor_type or interface.name == 'Window' or interface.name == 'Location',
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_interface.py b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
index fbb57bb..2ae2d22 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_interface.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
@@ -564,8 +564,8 @@
     context.update({
         'conditionally_enabled_methods': conditionally_enabled_methods,
         'custom_registration_methods': custom_registration_methods,
-        'has_origin_safe_method_setter': any(
-            method['is_check_security_for_frame'] and not method['is_read_only']
+        'has_origin_safe_method_setter': is_global and any(
+            method['is_check_security_for_receiver'] and not method['is_unforgeable']
             for method in methods),
         'has_private_script': any(attribute['is_implemented_in_private_script'] for attribute in attributes) or
             any(method['is_implemented_in_private_script'] for method in methods),
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_methods.py b/third_party/WebKit/Source/bindings/scripts/v8_methods.py
index 3ac9276e..8d37950 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_methods.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_methods.py
@@ -90,23 +90,21 @@
     is_call_with_this_value = has_extended_attribute_value(method, 'CallWith', 'ThisValue')
     if is_call_with_script_state or is_call_with_this_value:
         includes.add('bindings/core/v8/ScriptState.h')
-    is_check_security_for_node = 'CheckSecurity' in extended_attributes
-    if is_check_security_for_node:
+
+    # [CheckSecurity]
+    is_do_not_check_security = 'DoNotCheckSecurity' in extended_attributes
+    is_check_security_for_receiver = (
+        has_extended_attribute_value(interface, 'CheckSecurity', 'Receiver') and
+        not is_do_not_check_security)
+    is_check_security_for_return_value = (
+        has_extended_attribute_value(method, 'CheckSecurity', 'ReturnValue'))
+    if is_check_security_for_receiver or is_check_security_for_return_value:
         includes.add('bindings/core/v8/BindingSecurity.h')
+
     is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes
     if is_custom_element_callbacks:
         includes.add('core/dom/custom/CustomElementProcessingStack.h')
 
-    is_do_not_check_security = 'DoNotCheckSecurity' in extended_attributes
-
-    is_check_security_for_frame = (
-        has_extended_attribute_value(interface, 'CheckSecurity', 'Frame') and
-        not is_do_not_check_security)
-
-    is_check_security_for_window = (
-        has_extended_attribute_value(interface, 'CheckSecurity', 'Window') and
-        not is_do_not_check_security)
-
     is_raises_exception = 'RaisesException' in extended_attributes
     is_custom_call_prologue = has_extended_attribute_value(method, 'Custom', 'CallPrologue')
     is_custom_call_epilogue = has_extended_attribute_value(method, 'Custom', 'CallEpilogue')
@@ -143,8 +141,7 @@
                 method, CUSTOM_REGISTRATION_EXTENDED_ATTRIBUTES),
         'has_exception_state':
             is_raises_exception or
-            is_check_security_for_frame or
-            is_check_security_for_window or
+            is_check_security_for_receiver or
             any(argument for argument in arguments
                 if (argument.idl_type.name == 'SerializedScriptValue' or
                     argument_conversion_needs_exception_state(method, argument))),
@@ -153,9 +150,8 @@
         'is_call_with_script_arguments': is_call_with_script_arguments,
         'is_call_with_script_state': is_call_with_script_state,
         'is_call_with_this_value': is_call_with_this_value,
-        'is_check_security_for_frame': is_check_security_for_frame,
-        'is_check_security_for_node': is_check_security_for_node,
-        'is_check_security_for_window': is_check_security_for_window,
+        'is_check_security_for_receiver': is_check_security_for_receiver,
+        'is_check_security_for_return_value': is_check_security_for_return_value,
         'is_custom': 'Custom' in extended_attributes and
             not (is_custom_call_prologue or is_custom_call_epilogue),
         'is_custom_call_prologue': is_custom_call_prologue,
@@ -170,8 +166,8 @@
         'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
         'is_post_message': is_post_message,
         'is_raises_exception': is_raises_exception,
-        'is_read_only': is_unforgeable(interface, method),
         'is_static': is_static,
+        'is_unforgeable': is_unforgeable(interface, method),
         'is_variadic': arguments and arguments[-1].is_variadic,
         'measure_as': v8_utilities.measure_as(method, interface),  # [MeasureAs]
         'name': name,
diff --git a/third_party/WebKit/Source/bindings/templates/attributes.cpp b/third_party/WebKit/Source/bindings/templates/attributes.cpp
index e7a68af..89604a19 100644
--- a/third_party/WebKit/Source/bindings/templates/attributes.cpp
+++ b/third_party/WebKit/Source/bindings/templates/attributes.cpp
@@ -53,10 +53,9 @@
     {% if attribute.is_call_with_script_state %}
     ScriptState* scriptState = ScriptState::current(info.GetIsolate());
     {% endif %}
-    {% if ((attribute.is_check_security_for_frame or
-            attribute.is_check_security_for_window) and
+    {% if (attribute.is_check_security_for_receiver and
            not attribute.is_data_type_property) or
-          attribute.is_check_security_for_node or
+          attribute.is_check_security_for_return_value or
           attribute.is_getter_raises_exception %}
     ExceptionState exceptionState(ExceptionState::GetterContext, "{{attribute.name}}", "{{interface_name}}", holder, info.GetIsolate());
     {% endif %}
@@ -77,26 +76,16 @@
     {% endif %}
     {# Security checks #}
     {% if not attribute.is_data_type_property %}
-    {% if attribute.is_check_security_for_window %}
-    if (LocalDOMWindow* window = impl->toDOMWindow()) {
-        if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), window->frame(), exceptionState)) {
-            v8SetReturnValueNull(info);
-            exceptionState.throwIfNeeded();
-            return;
-        }
-        if (!window->document())
-            return;
-    }
-    {% elif attribute.is_check_security_for_frame %}
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    {% if attribute.is_check_security_for_receiver %}
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         v8SetReturnValueNull(info);
         exceptionState.throwIfNeeded();
         return;
     }
     {% endif %}
     {% endif %}
-    {% if attribute.is_check_security_for_node %}
-    if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), {{attribute.cpp_value}}, exceptionState)) {
+    {% if attribute.is_check_security_for_return_value %}
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), {{attribute.cpp_value}}, exceptionState)) {
         v8SetReturnValueNull(info);
         exceptionState.throwIfNeeded();
         return;
@@ -250,9 +239,8 @@
           ((not attribute.is_replaceable and
             not attribute.constructor_type and
             not attribute.is_data_type_property) and
-           (attribute.is_check_security_for_frame or
-            attribute.is_check_security_for_node or
-            attribute.is_check_security_for_window)) %}
+           (attribute.is_check_security_for_receiver or
+            attribute.is_check_security_for_return_value)) %}
     {% set raise_exception = 1 %}
     {% else %}
     {% set raise_exception = 0 %}
@@ -298,30 +286,16 @@
     {% if not attribute.is_replaceable and
           not attribute.constructor_type %}
     {% if not attribute.is_data_type_property %}
-    {% if attribute.is_check_security_for_window %}
-    if (LocalDOMWindow* window = impl->toDOMWindow()) {
-        if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), window->frame(), exceptionState)) {
-            v8SetReturnValue(info, v8Value);
-            exceptionState.throwIfNeeded();
-            return;
-        }
-        if (!window->document())
-            return;
-    }
-    {% elif attribute.is_check_security_for_frame %}
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    {% if attribute.is_check_security_for_receiver %}
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         v8SetReturnValue(info, v8Value);
         exceptionState.throwIfNeeded();
         return;
     }
     {% endif %}
     {% endif %}
-    {% if attribute.is_check_security_for_node %}
-    if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), {{attribute.cpp_value}}, exceptionState)) {
-        v8SetReturnValue(info, v8Value);
-        exceptionState.throwIfNeeded();
-        return;
-    }
+    {% if attribute.is_check_security_for_return_value %}
+#error Attribute setter with the security check for the return value is not supported.
     {% endif %}
     {% endif %}{# not attribute.is_replaceable and
                   not attribute.constructor_type #}
diff --git a/third_party/WebKit/Source/bindings/templates/interface.cpp b/third_party/WebKit/Source/bindings/templates/interface.cpp
index 9616b9a2..a44d2d1 100644
--- a/third_party/WebKit/Source/bindings/templates/interface.cpp
+++ b/third_party/WebKit/Source/bindings/templates/interface.cpp
@@ -450,7 +450,7 @@
     {{cpp_class}}* impl = {{v8_class}}::toImpl(holder);
     v8::String::Utf8Value attributeName(name);
     ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "{{interface_name}}", info.Holder(), info.GetIsolate());
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         exceptionState.throwIfNeeded();
         return;
     }
@@ -624,11 +624,11 @@
        (cpp_class, method.name, world_suffix) %}
 {% set setter_callback =
        '{0}V8Internal::{0}OriginSafeMethodSetterCallback'.format(cpp_class)
-       if not method.is_read_only else '0' %}
+       if not method.is_unforgeable else '0' %}
 {% if method.is_per_world_bindings %}
 {% set getter_callback_for_main_world = '%sForMainWorld' % getter_callback %}
 {% set setter_callback_for_main_world = '%sForMainWorld' % setter_callback
-       if not method.is_read_only else '0' %}
+       if not method.is_unforgeable else '0' %}
 {% else %}
 {% set getter_callback_for_main_world = '0' %}
 {% set setter_callback_for_main_world = '0' %}
diff --git a/third_party/WebKit/Source/bindings/templates/interface_base.cpp b/third_party/WebKit/Source/bindings/templates/interface_base.cpp
index 0e365a6..3ac4590 100644
--- a/third_party/WebKit/Source/bindings/templates/interface_base.cpp
+++ b/third_party/WebKit/Source/bindings/templates/interface_base.cpp
@@ -63,7 +63,7 @@
     {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
     v8::String::Utf8Value attributeName(name);
     ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "{{interface_name}}", info.Holder(), info.GetIsolate());
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         exceptionState.throwIfNeeded();
         return false;
     }
@@ -132,7 +132,7 @@
 {
     // TODO(jochen): Take accessingContext into account.
     {{cpp_class}}* impl = {{v8_class}}::toImpl(accessedObject);
-    return BindingSecurity::shouldAllowAccessToFrame(v8::Isolate::GetCurrent(), callingDOMWindow(v8::Isolate::GetCurrent()), impl->frame(), DoNotReportSecurityError);
+    return BindingSecurity::shouldAllowAccessTo(v8::Isolate::GetCurrent(), callingDOMWindow(v8::Isolate::GetCurrent()), impl, DoNotReportSecurityError);
 }
 
 {% endif %}
diff --git a/third_party/WebKit/Source/bindings/templates/methods.cpp b/third_party/WebKit/Source/bindings/templates/methods.cpp
index 0a18d9b..5f8285bd 100644
--- a/third_party/WebKit/Source/bindings/templates/methods.cpp
+++ b/third_party/WebKit/Source/bindings/templates/methods.cpp
@@ -27,23 +27,21 @@
     CustomElementProcessingStack::CallbackDeliveryScope deliveryScope;
     {% endif %}
     {# Security checks #}
-    {% if method.is_check_security_for_window %}
-    if (LocalDOMWindow* window = impl->toDOMWindow()) {
-        if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), window->frame(), exceptionState)) {
-            {{propagate_error_with_exception_state(method) | indent(12)}}
-        }
-        if (!window->document())
-            return;
-    }
-    {% elif method.is_check_security_for_frame %}
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
-        {{propagate_error_with_exception_state(method) | indent(8)}}
+    {% if method.is_check_security_for_receiver %}
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
+        {% if not method.returns_promise %}
+        exceptionState.throwIfNeeded();
+        {% endif %}
+        return;
     }
     {% endif %}
-    {% if method.is_check_security_for_node %}
-    if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->{{method.name}}(exceptionState), exceptionState)) {
+    {% if method.is_check_security_for_return_value %}
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), {{method.cpp_value}}, exceptionState)) {
         v8SetReturnValueNull(info);
-        {{propagate_error_with_exception_state(method) | indent(8)}}
+        {% if not method.returns_promise %}
+        exceptionState.throwIfNeeded();
+        {% endif %}
+        return;
     }
     {% endif %}
     {# Call method #}
@@ -536,7 +534,7 @@
         return;
     }
     {{cpp_class}}* impl = {{v8_class}}::toImpl(holder);
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), DoNotReportSecurityError)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, DoNotReportSecurityError)) {
         v8SetReturnValue(info, domTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked());
         return;
     }
diff --git a/third_party/WebKit/Source/bindings/tests/idls/core/TestInterfaceCheckSecurity.idl b/third_party/WebKit/Source/bindings/tests/idls/core/TestInterfaceCheckSecurity.idl
index a29dd81..5aaf41d1 100644
--- a/third_party/WebKit/Source/bindings/tests/idls/core/TestInterfaceCheckSecurity.idl
+++ b/third_party/WebKit/Source/bindings/tests/idls/core/TestInterfaceCheckSecurity.idl
@@ -27,7 +27,8 @@
  */
 
 [
-    CheckSecurity=Frame,
+    CheckSecurity=Receiver,
+    Global,
 ] interface TestInterfaceCheckSecurity {
     readonly attribute long readonlyLongAttribute;
     attribute long longAttribute;
diff --git a/third_party/WebKit/Source/bindings/tests/idls/core/TestObject.idl b/third_party/WebKit/Source/bindings/tests/idls/core/TestObject.idl
index 8258bce..ec0fe4e 100644
--- a/third_party/WebKit/Source/bindings/tests/idls/core/TestObject.idl
+++ b/third_party/WebKit/Source/bindings/tests/idls/core/TestObject.idl
@@ -177,7 +177,7 @@
     [CallWith=ExecutionContext] attribute any callWithExecutionContextAnyAttribute;
     [CallWith=ScriptState] attribute any callWithScriptStateAnyAttribute;
     [CallWith=(ExecutionContext,ScriptState)] attribute any callWithExecutionContextAndScriptStateAnyAttribute;
-    [CheckSecurity=Node] readonly attribute Document checkSecurityForNodeReadonlyDocumentAttribute; // All uses are read only
+    [CheckSecurity=ReturnValue] readonly attribute Document checkSecurityForNodeReadonlyDocumentAttribute; // All uses are read only
     [Conditional=CONDITION] attribute long conditionalLongAttribute;
     // Constructors: FIXME: replace suffix with [ConstructorAttribute]
     attribute TestInterfaceEmptyConstructor testInterfaceEmptyConstructorAttribute;
@@ -518,7 +518,7 @@
     [CallWith=ActiveWindow] void callWithActiveWindow();
     [CallWith=(ActiveWindow,FirstWindow)] void callWithActiveWindowScriptWindow();
     [CallWith=ThisValue] void callWithThisValue();
-    [CheckSecurity=Node] void checkSecurityForNodeVoidMethod();
+    [CheckSecurity=ReturnValue] void checkSecurityForNodeVoidMethod();
     [Conditional=CONDITION] void conditionalConditionVoidMethod();
     [Conditional=CONDITION] static void conditionalConditionStaticVoidMethod();
     [Custom] void customVoidMethod();
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp
index 2293a54..36045240 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp
@@ -44,7 +44,7 @@
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(info.Holder());
     v8::String::Utf8Value attributeName(name);
     ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "TestInterfaceCheckSecurity", info.Holder(), info.GetIsolate());
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         exceptionState.throwIfNeeded();
         return false;
     }
@@ -57,7 +57,7 @@
     v8::Local<v8::Object> holder = info.Holder();
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(holder);
     ExceptionState exceptionState(ExceptionState::GetterContext, "readonlyLongAttribute", "TestInterfaceCheckSecurity", holder, info.GetIsolate());
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         v8SetReturnValueNull(info);
         exceptionState.throwIfNeeded();
         return;
@@ -77,7 +77,7 @@
     v8::Local<v8::Object> holder = info.Holder();
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(holder);
     ExceptionState exceptionState(ExceptionState::GetterContext, "longAttribute", "TestInterfaceCheckSecurity", holder, info.GetIsolate());
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         v8SetReturnValueNull(info);
         exceptionState.throwIfNeeded();
         return;
@@ -97,7 +97,7 @@
     v8::Local<v8::Object> holder = info.Holder();
     ExceptionState exceptionState(ExceptionState::SetterContext, "longAttribute", "TestInterfaceCheckSecurity", holder, info.GetIsolate());
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(holder);
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         v8SetReturnValue(info, v8Value);
         exceptionState.throwIfNeeded();
         return;
@@ -228,14 +228,14 @@
 {
     // TODO(jochen): Take accessingContext into account.
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(accessedObject);
-    return BindingSecurity::shouldAllowAccessToFrame(v8::Isolate::GetCurrent(), callingDOMWindow(v8::Isolate::GetCurrent()), impl->frame(), DoNotReportSecurityError);
+    return BindingSecurity::shouldAllowAccessTo(v8::Isolate::GetCurrent(), callingDOMWindow(v8::Isolate::GetCurrent()), impl, DoNotReportSecurityError);
 }
 
 static void voidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
 {
     ExceptionState exceptionState(ExceptionState::ExecutionContext, "voidMethod", "TestInterfaceCheckSecurity", info.Holder(), info.GetIsolate());
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(info.Holder());
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         exceptionState.throwIfNeeded();
         return;
     }
@@ -276,7 +276,7 @@
         return;
     }
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(holder);
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), DoNotReportSecurityError)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, DoNotReportSecurityError)) {
         v8SetReturnValue(info, domTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked());
         return;
     }
@@ -324,7 +324,7 @@
         return;
     }
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(holder);
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), DoNotReportSecurityError)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, DoNotReportSecurityError)) {
         v8SetReturnValue(info, domTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked());
         return;
     }
@@ -372,7 +372,7 @@
         return;
     }
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(holder);
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), DoNotReportSecurityError)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, DoNotReportSecurityError)) {
         v8SetReturnValue(info, domTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked());
         return;
     }
@@ -420,7 +420,7 @@
         return;
     }
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(holder);
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), DoNotReportSecurityError)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, DoNotReportSecurityError)) {
         v8SetReturnValue(info, domTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked());
         return;
     }
@@ -468,7 +468,7 @@
         return;
     }
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(holder);
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), DoNotReportSecurityError)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, DoNotReportSecurityError)) {
         v8SetReturnValue(info, domTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked());
         return;
     }
@@ -497,7 +497,7 @@
     TestInterfaceCheckSecurity* impl = V8TestInterfaceCheckSecurity::toImpl(holder);
     v8::String::Utf8Value attributeName(name);
     ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "TestInterfaceCheckSecurity", info.Holder(), info.GetIsolate());
-    if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->frame(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl, exceptionState)) {
         exceptionState.throwIfNeeded();
         return;
     }
@@ -515,16 +515,16 @@
 } // namespace TestInterfaceCheckSecurityV8Internal
 
 const V8DOMConfiguration::AccessorConfiguration V8TestInterfaceCheckSecurityAccessors[] = {
-    {"readonlyLongAttribute", TestInterfaceCheckSecurityV8Internal::readonlyLongAttributeAttributeGetterCallback, 0, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
-    {"longAttribute", TestInterfaceCheckSecurityV8Internal::longAttributeAttributeGetterCallback, TestInterfaceCheckSecurityV8Internal::longAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
-    {"doNotCheckSecurityLongAttribute", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityLongAttributeAttributeGetterCallback, TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityLongAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
-    {"doNotCheckSecurityReadonlyLongAttribute", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityReadonlyLongAttributeAttributeGetterCallback, 0, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
-    {"doNotCheckSecurityOnSetterLongAttribute", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityOnSetterLongAttributeAttributeGetterCallback, TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityOnSetterLongAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
-    {"doNotCheckSecurityReplaceableReadonlyLongAttribute", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityReplaceableReadonlyLongAttributeAttributeGetterCallback, TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityReplaceableReadonlyLongAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
+    {"readonlyLongAttribute", TestInterfaceCheckSecurityV8Internal::readonlyLongAttributeAttributeGetterCallback, 0, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder},
+    {"longAttribute", TestInterfaceCheckSecurityV8Internal::longAttributeAttributeGetterCallback, TestInterfaceCheckSecurityV8Internal::longAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder},
+    {"doNotCheckSecurityLongAttribute", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityLongAttributeAttributeGetterCallback, TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityLongAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder},
+    {"doNotCheckSecurityReadonlyLongAttribute", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityReadonlyLongAttributeAttributeGetterCallback, 0, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder},
+    {"doNotCheckSecurityOnSetterLongAttribute", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityOnSetterLongAttributeAttributeGetterCallback, TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityOnSetterLongAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder},
+    {"doNotCheckSecurityReplaceableReadonlyLongAttribute", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityReplaceableReadonlyLongAttributeAttributeGetterCallback, TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityReplaceableReadonlyLongAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder},
 };
 
 const V8DOMConfiguration::MethodConfiguration V8TestInterfaceCheckSecurityMethods[] = {
-    {"voidMethod", TestInterfaceCheckSecurityV8Internal::voidMethodMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
+    {"voidMethod", TestInterfaceCheckSecurityV8Internal::voidMethodMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance},
 };
 
 static void installV8TestInterfaceCheckSecurityTemplate(v8::Local<v8::FunctionTemplate> functionTemplate, v8::Isolate* isolate)
@@ -544,21 +544,22 @@
     ALLOW_UNUSED_LOCAL(context);
     instanceTemplate->SetAccessCheckCallback(TestInterfaceCheckSecurityV8Internal::securityCheck, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&V8TestInterfaceCheckSecurity::wrapperTypeInfo)));
     const V8DOMConfiguration::AttributeConfiguration doNotCheckSecurityVoidMethodOriginSafeAttributeConfiguration = {
-        "doNotCheckSecurityVoidMethod", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityVoidMethodOriginSafeMethodGetterCallback, TestInterfaceCheckSecurityV8Internal::TestInterfaceCheckSecurityOriginSafeMethodSetterCallback, 0, 0, &V8TestInterfaceCheckSecurity::wrapperTypeInfo, v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder,
+        "doNotCheckSecurityVoidMethod", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityVoidMethodOriginSafeMethodGetterCallback, TestInterfaceCheckSecurityV8Internal::TestInterfaceCheckSecurityOriginSafeMethodSetterCallback, 0, 0, &V8TestInterfaceCheckSecurity::wrapperTypeInfo, v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder,
     };
     V8DOMConfiguration::installAttribute(isolate, instanceTemplate, prototypeTemplate, doNotCheckSecurityVoidMethodOriginSafeAttributeConfiguration);
     const V8DOMConfiguration::AttributeConfiguration doNotCheckSecurityDoNotCheckSignatureVoidMethodOriginSafeAttributeConfiguration = {
-        "doNotCheckSecurityDoNotCheckSignatureVoidMethod", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityDoNotCheckSignatureVoidMethodOriginSafeMethodGetterCallback, TestInterfaceCheckSecurityV8Internal::TestInterfaceCheckSecurityOriginSafeMethodSetterCallback, 0, 0, &V8TestInterfaceCheckSecurity::wrapperTypeInfo, v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::DoNotCheckHolder,
+        "doNotCheckSecurityDoNotCheckSignatureVoidMethod", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityDoNotCheckSignatureVoidMethodOriginSafeMethodGetterCallback, TestInterfaceCheckSecurityV8Internal::TestInterfaceCheckSecurityOriginSafeMethodSetterCallback, 0, 0, &V8TestInterfaceCheckSecurity::wrapperTypeInfo, v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::DoNotCheckHolder,
     };
     V8DOMConfiguration::installAttribute(isolate, instanceTemplate, prototypeTemplate, doNotCheckSecurityDoNotCheckSignatureVoidMethodOriginSafeAttributeConfiguration);
     const V8DOMConfiguration::AttributeConfiguration doNotCheckSecurityPerWorldBindingsVoidMethodOriginSafeAttributeConfiguration = {
-        "doNotCheckSecurityPerWorldBindingsVoidMethod", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityPerWorldBindingsVoidMethodOriginSafeMethodGetterCallback, TestInterfaceCheckSecurityV8Internal::TestInterfaceCheckSecurityOriginSafeMethodSetterCallback, TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityPerWorldBindingsVoidMethodOriginSafeMethodGetterCallbackForMainWorld, TestInterfaceCheckSecurityV8Internal::TestInterfaceCheckSecurityOriginSafeMethodSetterCallbackForMainWorld, &V8TestInterfaceCheckSecurity::wrapperTypeInfo, v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder,
+        "doNotCheckSecurityPerWorldBindingsVoidMethod", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityPerWorldBindingsVoidMethodOriginSafeMethodGetterCallback, TestInterfaceCheckSecurityV8Internal::TestInterfaceCheckSecurityOriginSafeMethodSetterCallback, TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityPerWorldBindingsVoidMethodOriginSafeMethodGetterCallbackForMainWorld, TestInterfaceCheckSecurityV8Internal::TestInterfaceCheckSecurityOriginSafeMethodSetterCallbackForMainWorld, &V8TestInterfaceCheckSecurity::wrapperTypeInfo, v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder,
     };
     V8DOMConfiguration::installAttribute(isolate, instanceTemplate, prototypeTemplate, doNotCheckSecurityPerWorldBindingsVoidMethodOriginSafeAttributeConfiguration);
     const V8DOMConfiguration::AttributeConfiguration doNotCheckSecurityUnforgeableVoidMethodOriginSafeAttributeConfiguration = {
         "doNotCheckSecurityUnforgeableVoidMethod", TestInterfaceCheckSecurityV8Internal::doNotCheckSecurityUnforgeableVoidMethodOriginSafeMethodGetterCallback, 0, 0, 0, &V8TestInterfaceCheckSecurity::wrapperTypeInfo, v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder,
     };
     V8DOMConfiguration::installAttribute(isolate, instanceTemplate, prototypeTemplate, doNotCheckSecurityUnforgeableVoidMethodOriginSafeAttributeConfiguration);
+    functionTemplate->SetHiddenPrototype(true);
 
     // Custom toString template
     functionTemplate->Set(v8AtomicString(isolate, "toString"), V8PerIsolateData::from(isolate)->toStringTemplate());
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
index f6c7d93c..08835a4 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
@@ -2586,7 +2586,7 @@
     v8::Local<v8::Object> holder = info.Holder();
     TestObject* impl = V8TestObject::toImpl(holder);
     ExceptionState exceptionState(ExceptionState::GetterContext, "checkSecurityForNodeReadonlyDocumentAttribute", "TestObject", holder, info.GetIsolate());
-    if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->checkSecurityForNodeReadonlyDocumentAttribute(), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->checkSecurityForNodeReadonlyDocumentAttribute(), exceptionState)) {
         v8SetReturnValueNull(info);
         exceptionState.throwIfNeeded();
         return;
@@ -10492,7 +10492,7 @@
 static void checkSecurityForNodeVoidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
 {
     TestObject* impl = V8TestObject::toImpl(info.Holder());
-    if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->checkSecurityForNodeVoidMethod(exceptionState), exceptionState)) {
+    if (!BindingSecurity::shouldAllowAccessTo(info.GetIsolate(), callingDOMWindow(info.GetIsolate()), impl->checkSecurityForNodeVoidMethod(), exceptionState)) {
         v8SetReturnValueNull(info);
         exceptionState.throwIfNeeded();
         return;
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in
index 3555ea1..062ef004 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.in
+++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -225,9 +225,9 @@
 min-height interpolable, initial=initialMinSize, converter=convertLengthSizing
 min-width interpolable, initial=initialMinSize, converter=convertLengthSizing
 mix-blend-mode runtime_flag=CSSCompositing, type_name=blink::WebBlendMode, name_for_methods=BlendMode
-motion-offset runtime_flag=CSSMotionPath, interpolable, converter=convertLength
-motion-path runtime_flag=CSSMotionPath, custom_all
-motion-rotation runtime_flag=CSSMotionPath, interpolable, custom_all
+motion-offset interpolable, converter=convertLength
+motion-path custom_all
+motion-rotation interpolable, custom_all
 object-fit type_name=ObjectFit
 object-position interpolable, converter=convertPosition
 opacity interpolable, type_name=float
@@ -470,7 +470,7 @@
 list-style longhands=list-style-type;list-style-position;list-style-image
 margin longhands=margin-top;margin-right;margin-bottom;margin-left
 marker longhands=marker-start;marker-mid;marker-end
-motion runtime_flag=CSSMotionPath, longhands=motion-path;motion-offset;motion-rotation
+motion longhands=motion-path;motion-offset;motion-rotation
 outline longhands=outline-color;outline-style;outline-width
 overflow longhands=overflow-x;overflow-y
 padding longhands=padding-top;padding-right;padding-bottom;padding-left
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index 8f17a4de..2b4ff3a 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -2419,11 +2419,9 @@
         return nullptr;
 
     case CSSPropertyMotion:
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
         return valuesForShorthandProperty(motionShorthand(), style, layoutObject, styledNode, allowVisitedStyle);
 
     case CSSPropertyMotionPath: {
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
         const StyleMotionPath* styleMotionPath = style.motionPath();
         if (!styleMotionPath)
             return cssValuePool().createIdentifierValue(CSSValueNone);
@@ -2433,11 +2431,9 @@
     }
 
     case CSSPropertyMotionOffset:
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
         return zoomAdjustedPixelValueForLength(style.motionOffset(), style);
 
     case CSSPropertyMotionRotation: {
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
         RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
         if (style.motionRotationType() == MotionRotationAuto)
             list->append(cssValuePool().createIdentifierValue(CSSValueAuto));
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 260d1a9..6d18201 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -2099,13 +2099,10 @@
     case CSSPropertyTextDecorationLine:
         return consumeTextDecorationLine(m_range);
     case CSSPropertyMotionPath:
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
         return consumeMotionPath(m_range);
     case CSSPropertyMotionOffset:
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
         return consumeLengthOrPercent(m_range, m_context.mode(), ValueRangeAll);
     case CSSPropertyMotionRotation:
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
         return consumeMotionRotation(m_range, m_context.mode());
     case CSSPropertyWebkitTextEmphasisStyle:
         return consumeTextEmphasisStyle(m_range);
@@ -2692,7 +2689,6 @@
     case CSSPropertyPadding:
         return consume4Values(paddingShorthand(), important);
     case CSSPropertyMotion:
-        ASSERT(RuntimeEnabledFeatures::cssMotionPathEnabled());
         return consumeShorthandGreedily(motionShorthand(), important);
     case CSSPropertyWebkitTextEmphasis:
         return consumeShorthandGreedily(webkitTextEmphasisShorthand(), important);
diff --git a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp
index 2a63bf0e..e9695df 100644
--- a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp
@@ -21,61 +21,25 @@
 
 namespace blink {
 
-// TODO(leviw): This should take a CSSParserTokenRange
-static void findEndIndexOfVariableReference(const Vector<CSSParserToken>& resolvedTokens, unsigned startIndex, unsigned& endIndex, unsigned& commaIndex, bool& hasClosingBracket)
+bool CSSVariableResolver::resolveVariableTokensRecursive(CSSParserTokenRange range,
+    Vector<CSSParserToken>& result)
 {
-    endIndex = 0;
-    commaIndex = 0;
-    unsigned bracketCount = 1;
-    for (unsigned i = startIndex; i < resolvedTokens.size(); ++i) {
-        CSSParserTokenType type = resolvedTokens[i].type();
-
-        if (type == CommaToken && !commaIndex) {
-            commaIndex = i;
-        } else if (type == LeftParenthesisToken || type == FunctionToken) {
-            bracketCount++;
-        } else if (type == RightParenthesisToken) {
-            if (bracketCount == 1) {
-                hasClosingBracket = true;
-                endIndex = i;
-                return;
-            }
-            bracketCount--;
-        }
-    }
-    hasClosingBracket = false;
-    endIndex = resolvedTokens.size() - 1;
-}
-
-unsigned CSSVariableResolver::resolveVariableTokensRecursive(Vector<CSSParserToken>& resolvedTokens, unsigned startIndex)
-{
-    unsigned variableLocation = startIndex;
-    while (resolvedTokens[variableLocation].type() != IdentToken)
-        variableLocation++;
-
-    unsigned commaIndex;
-    unsigned endIndex;
-    bool hasClosingBracket;
-    // Find default value and match braces
-    findEndIndexOfVariableReference(resolvedTokens, variableLocation + 1, endIndex, commaIndex, hasClosingBracket);
-
-    unsigned length = endIndex - startIndex + 1;
-    unsigned varFunctionPosition = startIndex;
-
-    AtomicString variableName = resolvedTokens[variableLocation].value();
+    range.consumeWhitespace();
+    ASSERT(range.peek().type() == IdentToken);
+    AtomicString variableName = range.consumeIncludingWhitespace().value();
+    ASSERT(range.atEnd() || (range.peek().type() == CommaToken));
 
     if (m_variablesSeen.contains(variableName)) {
         m_cycleDetected = true;
-        resolvedTokens.clear();
-        return 0;
+        return false;
     }
 
     CSSVariableData* variableData = m_styleVariableData ? m_styleVariableData->getVariable(variableName) : nullptr;
     if (variableData) {
-        Vector<CSSParserToken> tokens(variableData->tokens());
+        Vector<CSSParserToken> tokens;
         if (variableData->needsVariableResolution()) {
             m_variablesSeen.add(variableName);
-            resolveVariableReferencesFromTokens(tokens);
+            resolveVariableReferencesFromTokens(variableData->tokens(), tokens);
             m_variablesSeen.remove(variableName);
 
             // The old variable data holds onto the backing string the new resolved CSSVariableData
@@ -83,56 +47,46 @@
             ASSERT(variableData->refCount() > 1);
 
             m_styleVariableData->setVariable(variableName, CSSVariableData::createResolved(tokens));
+        } else {
+            tokens = variableData->tokens();
         }
-        if (tokens.size()) {
-            resolvedTokens.remove(startIndex, length);
-            resolvedTokens.insert(startIndex, tokens);
-            return tokens.size();
+        if (!tokens.isEmpty()) {
+            result.appendVector(tokens);
+            return true;
         }
     }
 
-    // Fallback on default value if present
-    if (!commaIndex || m_cycleDetected) {
-        resolvedTokens.clear();
-        return 0;
-    }
+    if (range.atEnd())
+        return false;
 
-    // Move the tokens to the beginning of the variable reference
-    unsigned defaultValueStart = commaIndex + 1;
-    unsigned defaultValueLength = endIndex - commaIndex - (hasClosingBracket ? 1 : 0);
-    for (unsigned i = 0; i < defaultValueLength; ++i)
-        resolvedTokens[varFunctionPosition + i] = resolvedTokens[defaultValueStart + i];
-    resolvedTokens.remove(varFunctionPosition + defaultValueLength, length - defaultValueLength);
+    // Comma Token, as asserted above.
+    range.consume();
 
-    resolveVariableReferencesFromTokens(resolvedTokens);
-
-    return resolvedTokens.size();
+    resolveVariableReferencesFromTokens(range, result);
+    return true;
 }
 
-void CSSVariableResolver::resolveVariableReferencesFromTokens(Vector<CSSParserToken>& tokens)
+bool CSSVariableResolver::resolveVariableReferencesFromTokens(CSSParserTokenRange range,
+    Vector<CSSParserToken>& result)
 {
-    for (unsigned i = 0; i < tokens.size(); ++i) {
-        if (tokens[i].functionId() == CSSValueVar) {
-            unsigned validTokens = resolveVariableTokensRecursive(tokens, i);
-            if (validTokens < 1 || m_cycleDetected) {
-                tokens.clear();
-                break;
-            }
-            i += validTokens - 1;
+    while (!range.atEnd()) {
+        if (range.peek().functionId() != CSSValueVar) {
+            result.append(range.consume());
+        } else if (!resolveVariableTokensRecursive(range.consumeBlock(), result) || m_cycleDetected) {
+            result.clear();
+            return false;
         }
     }
+    return true;
 }
 
 void CSSVariableResolver::resolveAndApplyVariableReferences(StyleResolverState& state, CSSPropertyID id, const CSSVariableReferenceValue& value)
 {
     // TODO(leviw): This should be a stack
-    Vector<CSSParserToken> tokens = value.variableDataValue()->tokens();
-
     CSSVariableResolver resolver(state.style()->variables());
 
-    resolver.resolveVariableReferencesFromTokens(tokens);
-
-    if (!tokens.size())
+    Vector<CSSParserToken> tokens;
+    if (!resolver.resolveVariableReferencesFromTokens(value.variableDataValue()->tokens(), tokens))
         return;
 
     CSSParserContext context(HTMLStandardMode, 0);
@@ -154,10 +108,10 @@
     for (auto& variable : variables->m_data) {
         if (!variable.value->needsVariableResolution())
             continue;
-        Vector<CSSParserToken> resolvedTokens(variable.value->tokens());
+        Vector<CSSParserToken> resolvedTokens;
 
         CSSVariableResolver resolver(variables, variable.key);
-        resolver.resolveVariableReferencesFromTokens(resolvedTokens);
+        resolver.resolveVariableReferencesFromTokens(variable.value->tokens(), resolvedTokens);
 
         variable.value = CSSVariableData::createResolved(resolvedTokens);
     }
diff --git a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.h b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.h
index fb832cce..6b542fc 100644
--- a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.h
+++ b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.h
@@ -13,6 +13,7 @@
 
 namespace blink {
 
+class CSSParserTokenRange;
 class CSSVariableReferenceValue;
 class StyleResolverState;
 class StyleVariableData;
@@ -26,8 +27,8 @@
     CSSVariableResolver(StyleVariableData*);
     CSSVariableResolver(StyleVariableData*, AtomicString& variable);
 
-    unsigned resolveVariableTokensRecursive(Vector<CSSParserToken>&, unsigned startOffset);
-    void resolveVariableReferencesFromTokens(Vector<CSSParserToken>& tokens);
+    bool resolveVariableTokensRecursive(CSSParserTokenRange, Vector<CSSParserToken>& result);
+    bool resolveVariableReferencesFromTokens(CSSParserTokenRange tokens, Vector<CSSParserToken>& result);
 
     StyleVariableData* m_styleVariableData;
     HashSet<AtomicString> m_variablesSeen;
diff --git a/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp b/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp
index e93e8b3..624b4818 100644
--- a/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp
@@ -107,6 +107,12 @@
 
 void MatchedPropertiesCache::clear()
 {
+    // MatchedPropertiesCache must be cleared promptly because some
+    // destructors in the properties (e.g., ~FontFallbackList) expect that
+    // the destructors are called promptly without relying on a GC timing.
+    for (auto& cacheEntry : m_cache) {
+        cacheEntry.value->clear();
+    }
     m_cache.clear();
 }
 
diff --git a/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.h b/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.h
index ebfc882..d1887cf 100644
--- a/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.h
+++ b/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.h
@@ -94,6 +94,10 @@
     WTF_MAKE_NONCOPYABLE(MatchedPropertiesCache);
 public:
     MatchedPropertiesCache();
+    ~MatchedPropertiesCache()
+    {
+        ASSERT(m_cache.isEmpty());
+    }
 
     const CachedMatchedProperties* find(unsigned hash, const StyleResolverState&, const MatchedPropertiesVector&);
     void add(const ComputedStyle&, const ComputedStyle& parentStyle, unsigned hash, const MatchedPropertiesVector&);
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
index 35ab44b..4d343cda 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
@@ -165,6 +165,11 @@
 {
 }
 
+void StyleResolver::dispose()
+{
+    m_matchedPropertiesCache.clear();
+}
+
 void StyleResolver::initWatchedSelectorRules()
 {
     CSSSelectorWatch* watch = CSSSelectorWatch::fromIfExists(*m_document);
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.h b/third_party/WebKit/Source/core/css/resolver/StyleResolver.h
index 59e73e1..2e3c58a9 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.h
+++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.h
@@ -86,6 +86,7 @@
         return adoptPtrWillBeNoop(new StyleResolver(document));
     }
     ~StyleResolver();
+    void dispose();
 
     // FIXME: StyleResolver should not be keeping tree-walk state.
     // These should move to some global tree-walk state, or should be contained in a
diff --git a/third_party/WebKit/Source/core/dom/Attr.h b/third_party/WebKit/Source/core/dom/Attr.h
index 359a588..9bfd829 100644
--- a/third_party/WebKit/Source/core/dom/Attr.h
+++ b/third_party/WebKit/Source/core/dom/Attr.h
@@ -70,7 +70,7 @@
 
     String nodeValue() const override { return value(); }
     void setNodeValue(const String&) override;
-    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) override;
+    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) override;
 
     bool isAttributeNode() const override { return true; }
 
diff --git a/third_party/WebKit/Source/core/dom/Comment.h b/third_party/WebKit/Source/core/dom/Comment.h
index bdc5ebe..45a0444 100644
--- a/third_party/WebKit/Source/core/dom/Comment.h
+++ b/third_party/WebKit/Source/core/dom/Comment.h
@@ -37,7 +37,7 @@
 
     String nodeName() const override;
     NodeType nodeType() const override;
-    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) override;
+    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) override;
 };
 
 DEFINE_NODE_TYPE_CASTS(Comment, nodeType() == Node::COMMENT_NODE);
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 56c7aa9..22555f4 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -1103,7 +1103,7 @@
     String nodeName() const final;
     NodeType nodeType() const final;
     bool childTypeAllowed(NodeType) const final;
-    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) final;
+    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) final;
     void cloneDataFromDocument(const Document&);
 
 #if !ENABLE(OILPAN)
diff --git a/third_party/WebKit/Source/core/dom/DocumentFragment.h b/third_party/WebKit/Source/core/dom/DocumentFragment.h
index de58ffc..74788f62 100644
--- a/third_party/WebKit/Source/core/dom/DocumentFragment.h
+++ b/third_party/WebKit/Source/core/dom/DocumentFragment.h
@@ -47,7 +47,7 @@
 
 private:
     NodeType nodeType() const final;
-    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) override;
+    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) override;
     bool childTypeAllowed(NodeType) const override;
 
     bool isDocumentFragment() const = delete; // This will catch anyone doing an unnecessary check.
diff --git a/third_party/WebKit/Source/core/dom/Node.h b/third_party/WebKit/Source/core/dom/Node.h
index e7ab471e..18ea2ae 100644
--- a/third_party/WebKit/Source/core/dom/Node.h
+++ b/third_party/WebKit/Source/core/dom/Node.h
@@ -228,7 +228,7 @@
     PassRefPtrWillBeRawPtr<Node> appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
 
     bool hasChildren() const { return firstChild(); }
-    virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = false) = 0;
+    virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) = 0;
     void normalize();
 
     bool isSameNode(Node* other) const { return this == other; }
diff --git a/third_party/WebKit/Source/core/dom/Node.idl b/third_party/WebKit/Source/core/dom/Node.idl
index 5423489..3507934 100644
--- a/third_party/WebKit/Source/core/dom/Node.idl
+++ b/third_party/WebKit/Source/core/dom/Node.idl
@@ -57,8 +57,7 @@
     [TreatUndefinedAs=NullString, CustomElementCallbacks] attribute DOMString? textContent;
     [CustomElementCallbacks] void normalize();
 
-    // FIXME: The deep argument should have a default value false.
-    [NewObject, CustomElementCallbacks] Node cloneNode(optional boolean deep);
+    [NewObject, CustomElementCallbacks] Node cloneNode(optional boolean deep = false);
     boolean isEqualNode(Node? node);
 
     const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
diff --git a/third_party/WebKit/Source/core/dom/ProcessingInstruction.h b/third_party/WebKit/Source/core/dom/ProcessingInstruction.h
index 2d97897..48c3c64 100644
--- a/third_party/WebKit/Source/core/dom/ProcessingInstruction.h
+++ b/third_party/WebKit/Source/core/dom/ProcessingInstruction.h
@@ -82,7 +82,7 @@
 
     String nodeName() const override;
     NodeType nodeType() const override;
-    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) override;
+    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) override;
 
     InsertionNotificationRequest insertedInto(ContainerNode*) override;
     void removedFrom(ContainerNode*) override;
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
index 4fde5b99..a926715 100644
--- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp
+++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -429,6 +429,7 @@
 
     if (m_resolver) {
         TRACE_EVENT1("blink", "StyleEngine::clearResolver", "frame", document().frame());
+        m_resolver->dispose();
         m_resolver.clear();
     }
 }
diff --git a/third_party/WebKit/Source/core/dom/Text.h b/third_party/WebKit/Source/core/dom/Text.h
index 08178b7..fa8435d 100644
--- a/third_party/WebKit/Source/core/dom/Text.h
+++ b/third_party/WebKit/Source/core/dom/Text.h
@@ -70,7 +70,7 @@
 
 private:
     String nodeName() const override;
-    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) final;
+    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) final;
 
     bool isTextNode() const = delete; // This will catch anyone doing an unnecessary check.
 
diff --git a/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl b/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl
index cfb06f2..f783a41e 100644
--- a/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl
+++ b/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl
@@ -42,5 +42,5 @@
     // interface. Here, it's used to implement "Invoking the cloneNode() method
     // on a ShadowRoot instance must always throw a DATA_CLONE_ERR exception" as
     // Node.cloneNode() does not have [RaisesException].
-    [RaisesException] Node cloneNode([Default=Undefined] optional boolean deep);
+    [RaisesException] Node cloneNode(optional boolean deep = false);
 };
diff --git a/third_party/WebKit/Source/core/events/EventTarget.cpp b/third_party/WebKit/Source/core/events/EventTarget.cpp
index 85ebd98a..8ced267 100644
--- a/third_party/WebKit/Source/core/events/EventTarget.cpp
+++ b/third_party/WebKit/Source/core/events/EventTarget.cpp
@@ -94,6 +94,11 @@
     return nullptr;
 }
 
+const LocalDOMWindow* EventTarget::toDOMWindow() const
+{
+    return nullptr;
+}
+
 LocalDOMWindow* EventTarget::toDOMWindow()
 {
     return nullptr;
diff --git a/third_party/WebKit/Source/core/events/EventTarget.h b/third_party/WebKit/Source/core/events/EventTarget.h
index acd8940..5f56ecb0 100644
--- a/third_party/WebKit/Source/core/events/EventTarget.h
+++ b/third_party/WebKit/Source/core/events/EventTarget.h
@@ -125,6 +125,7 @@
     virtual ExecutionContext* executionContext() const = 0;
 
     virtual Node* toNode();
+    virtual const LocalDOMWindow* toDOMWindow() const;
     virtual LocalDOMWindow* toDOMWindow();
     virtual MessagePort* toMessagePort();
 
diff --git a/third_party/WebKit/Source/core/events/EventTarget.idl b/third_party/WebKit/Source/core/events/EventTarget.idl
index e4bcd44..b38ff757 100644
--- a/third_party/WebKit/Source/core/events/EventTarget.idl
+++ b/third_party/WebKit/Source/core/events/EventTarget.idl
@@ -21,7 +21,7 @@
 // https://dom.spec.whatwg.org/#interface-eventtarget
 
 [
-    CheckSecurity=Window,
+    CheckSecurity=Receiver,
     WillBeGarbageCollected,
     Exposed=(Window,Worker)
 ] interface EventTarget {
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.cpp b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
index 442a2d7..d48031c 100644
--- a/third_party/WebKit/Source/core/frame/DOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
@@ -230,7 +230,7 @@
 // exactly which details may be exposed to JavaScript.
 //
 // http://crbug.com/17325
-String DOMWindow::sanitizedCrossDomainAccessErrorMessage(LocalDOMWindow* callingWindow)
+String DOMWindow::sanitizedCrossDomainAccessErrorMessage(const LocalDOMWindow* callingWindow) const
 {
     if (!callingWindow || !callingWindow->document() || !frame())
         return String();
@@ -241,7 +241,7 @@
 
     ASSERT(!callingWindow->document()->securityOrigin()->canAccessCheckSuborigins(frame()->securityContext()->securityOrigin()));
 
-    SecurityOrigin* activeOrigin = callingWindow->document()->securityOrigin();
+    const SecurityOrigin* activeOrigin = callingWindow->document()->securityOrigin();
     String message = "Blocked a frame with origin \"" + activeOrigin->toString() + "\" from accessing a cross-origin frame.";
 
     // FIXME: Evaluate which details from 'crossDomainAccessErrorMessage' may safely be reported to JavaScript.
@@ -249,7 +249,7 @@
     return message;
 }
 
-String DOMWindow::crossDomainAccessErrorMessage(LocalDOMWindow* callingWindow)
+String DOMWindow::crossDomainAccessErrorMessage(const LocalDOMWindow* callingWindow) const
 {
     if (!callingWindow || !callingWindow->document() || !frame())
         return String();
@@ -259,8 +259,8 @@
         return String();
 
     // FIXME: This message, and other console messages, have extra newlines. Should remove them.
-    SecurityOrigin* activeOrigin = callingWindow->document()->securityOrigin();
-    SecurityOrigin* targetOrigin = frame()->securityContext()->securityOrigin();
+    const SecurityOrigin* activeOrigin = callingWindow->document()->securityOrigin();
+    const SecurityOrigin* targetOrigin = frame()->securityContext()->securityOrigin();
     ASSERT(!activeOrigin->canAccessCheckSuborigins(targetOrigin));
 
     String message = "Blocked a frame with origin \"" + activeOrigin->toString() + "\" from accessing a frame with origin \"" + targetOrigin->toString() + "\". ";
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.h b/third_party/WebKit/Source/core/frame/DOMWindow.h
index f8bedc4..7c2a6e4c 100644
--- a/third_party/WebKit/Source/core/frame/DOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/DOMWindow.h
@@ -184,8 +184,8 @@
 
     void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, LocalDOMWindow* source, ExceptionState&);
 
-    String sanitizedCrossDomainAccessErrorMessage(LocalDOMWindow* callingWindow);
-    String crossDomainAccessErrorMessage(LocalDOMWindow* callingWindow);
+    String sanitizedCrossDomainAccessErrorMessage(const LocalDOMWindow* callingWindow) const;
+    String crossDomainAccessErrorMessage(const LocalDOMWindow* callingWindow) const;
     bool isInsecureScriptAccess(LocalDOMWindow& callingWindow, const String& urlString);
 
     // FIXME: When this DOMWindow is no longer the active DOMWindow (i.e.,
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index 652db630..34fa2a0 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -474,6 +474,11 @@
     return m_document.get();
 }
 
+const LocalDOMWindow* LocalDOMWindow::toDOMWindow() const
+{
+    return this;
+}
+
 LocalDOMWindow* LocalDOMWindow::toDOMWindow()
 {
     return this;
@@ -1434,7 +1439,7 @@
     }
 }
 
-void LocalDOMWindow::printErrorMessage(const String& message)
+void LocalDOMWindow::printErrorMessage(const String& message) const
 {
     if (!isCurrentlyDisplayedInFrame())
         return;
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
index 318e84d0..4cbd839 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
@@ -82,6 +82,7 @@
 
     // EventTarget overrides:
     ExecutionContext* executionContext() const override;
+    const LocalDOMWindow* toDOMWindow() const override;
     LocalDOMWindow* toDOMWindow() override;
 
     // DOMWindow overrides:
@@ -165,7 +166,7 @@
 
     FrameConsole* frameConsole() const;
 
-    void printErrorMessage(const String&);
+    void printErrorMessage(const String&) const;
 
     void postMessageTimerFired(PostMessageTimer*);
     void removePostMessageTimer(PostMessageTimer*);
diff --git a/third_party/WebKit/Source/core/frame/Location.idl b/third_party/WebKit/Source/core/frame/Location.idl
index d68eaf7..592474d 100644
--- a/third_party/WebKit/Source/core/frame/Location.idl
+++ b/third_party/WebKit/Source/core/frame/Location.idl
@@ -29,7 +29,7 @@
 // https://html.spec.whatwg.org/#the-location-interface
 
 [
-    CheckSecurity=Frame,
+    CheckSecurity=Receiver,
     Unforgeable,
     WillBeGarbageCollected,
 ] interface Location {
diff --git a/third_party/WebKit/Source/core/frame/Window.idl b/third_party/WebKit/Source/core/frame/Window.idl
index 8a3292d9..6691a833 100644
--- a/third_party/WebKit/Source/core/frame/Window.idl
+++ b/third_party/WebKit/Source/core/frame/Window.idl
@@ -28,7 +28,7 @@
 
 // FIXME: explain all uses of [DoNotCheckSecurity]
 [
-    CheckSecurity=Frame,
+    CheckSecurity=Receiver,
     ImplementedAs=DOMWindow,
     PrimaryGlobal,
 ] interface Window : EventTarget {
@@ -60,7 +60,7 @@
     // FIXME: opener should be of type any.
     [DoNotCheckSecurity, Custom=Setter] attribute Window opener;
     [Replaceable, DoNotCheckSecurity] readonly attribute Window parent;
-    [CheckSecurity=Node, Custom=Getter] readonly attribute Element? frameElement;
+    [CheckSecurity=ReturnValue, Custom=Getter] readonly attribute Element? frameElement;
     // FIXME: open() should have 4 optional arguments with defaults.
     [Custom] Window? open(DOMString url, DOMString target, optional DOMString features);
     // FIXME: These getters should not have [NotEnumerable].
diff --git a/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl b/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl
index 5759506..5def601 100644
--- a/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl
@@ -29,7 +29,7 @@
     [Reflect] attribute DOMString type;
     [Reflect] attribute DOMString width;
     [Reflect] attribute DOMString height;
-    [CheckSecurity=Node, RaisesException] Document? getSVGDocument();
+    [CheckSecurity=ReturnValue, RaisesException] Document? getSVGDocument();
     // FIXME: The spec has a legacycaller any (any... arguments); crbug.com/465009
 
     // obsolete members
diff --git a/third_party/WebKit/Source/core/html/HTMLFrameElement.idl b/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
index bd50b0ce..54e2901 100644
--- a/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
@@ -27,7 +27,7 @@
     [Reflect] attribute DOMString frameBorder;
     [Reflect, URL] attribute DOMString longDesc;
     [Reflect] attribute boolean noResize;
-    [CheckSecurity=Node] readonly attribute Document? contentDocument;
+    [CheckSecurity=ReturnValue] readonly attribute Document? contentDocument;
     readonly attribute Window? contentWindow;
 
     [Reflect, TreatNullAs=EmptyString] attribute DOMString marginHeight;
diff --git a/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl b/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
index 247a3902..2b834dd 100644
--- a/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
@@ -29,9 +29,9 @@
     [Reflect] attribute boolean allowFullscreen;
     [Reflect] attribute DOMString width;
     [Reflect] attribute DOMString height;
-    [CheckSecurity=Node] readonly attribute Document? contentDocument;
+    [CheckSecurity=ReturnValue] readonly attribute Document? contentDocument;
     readonly attribute Window? contentWindow;
-    [CheckSecurity=Node, RaisesException] Document? getSVGDocument();
+    [CheckSecurity=ReturnValue, RaisesException] Document? getSVGDocument();
     [RuntimeEnabled=ReferrerPolicyAttribute, Reflect, ReflectOnly=("","no-referrer","origin","no-referrer-when-downgrade","origin-when-cross-origin","unsafe-url"), ReflectMissing="", ReflectInvalid=""] attribute DOMString referrerpolicy;
 
 
diff --git a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
index 76eab4d..de182035 100644
--- a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -603,8 +603,7 @@
 {
     ASSERT(m_sheet);
     ASSERT(m_sheet->ownerNode() == m_owner);
-    m_sheet->clearOwnerNode();
-    m_sheet = nullptr;
+    m_sheet.release()->clearOwnerNode();
 }
 
 bool LinkStyle::styleSheetIsLoading() const
diff --git a/third_party/WebKit/Source/core/html/HTMLObjectElement.idl b/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
index a936771..d0f62615 100644
--- a/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
@@ -33,9 +33,9 @@
     [ImplementedAs=formOwner] readonly attribute HTMLFormElement? form;
     [Reflect] attribute DOMString width;
     [Reflect] attribute DOMString height;
-    [CheckSecurity=Node] readonly attribute Document? contentDocument;
+    [CheckSecurity=ReturnValue] readonly attribute Document? contentDocument;
     // TODO(philipj): readonly attribute WindowProxy? contentWindow;
-    [CheckSecurity=Node, RaisesException] Document? getSVGDocument();
+    [CheckSecurity=ReturnValue, RaisesException] Document? getSVGDocument();
 
     readonly attribute boolean willValidate;
     readonly attribute ValidityState validity;
diff --git a/third_party/WebKit/Source/core/html/HTMLTemplateElement.h b/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
index 2185690..2574ec1 100644
--- a/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
@@ -48,7 +48,7 @@
     DocumentFragment* content() const;
 
 private:
-    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) override;
+    PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) override;
     void didMoveToNewDocument(Document& oldDocument) override;
 
     explicit HTMLTemplateElement(Document&);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
index 9309d9f..926fc41 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -160,7 +160,7 @@
     ScriptState::Scope scope(scriptState);
     v8::Isolate* isolate = scriptState->isolate();
     ExceptionState exceptionState(ExceptionState::ExecutionContext, "nodeAsScriptValue", "InjectedScriptHost", scriptState->context()->Global(), isolate);
-    if (!BindingSecurity::shouldAllowAccessToNode(isolate, callingDOMWindow(isolate), node, exceptionState))
+    if (!BindingSecurity::shouldAllowAccessTo(isolate, callingDOMWindow(isolate), node, exceptionState))
         return ScriptValue(scriptState, v8::Null(isolate));
     return ScriptValue(scriptState, toV8(node, scriptState->context()->Global(), isolate));
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
index 2ce5335c..755fb36 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -691,6 +691,7 @@
     OrderedFlexItemList orderedChildren;
     LayoutUnit sumFlexBaseSize;
     double totalFlexGrow;
+    double totalFlexShrink;
     double totalWeightedFlexShrink;
     LayoutUnit sumHypotheticalMainSize;
 
@@ -698,18 +699,22 @@
 
     m_orderIterator.first();
     LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
-    while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalWeightedFlexShrink, sumHypotheticalMainSize, relayoutChildren)) {
+    while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, sumHypotheticalMainSize, relayoutChildren)) {
         LayoutUnit containerMainInnerSize = mainAxisContentExtent(sumHypotheticalMainSize);
+        // availableFreeSpace is the initial amount of free space in this flexbox.
+        // remainingFreeSpace starts out at the same value but as we place and lay out
+        // flex items we subtract from it. Note that both values can be negative.
         LayoutUnit availableFreeSpace = containerMainInnerSize - sumFlexBaseSize;
+        LayoutUnit remainingFreeSpace = availableFreeSpace;
         FlexSign flexSign = (sumHypotheticalMainSize < containerMainInnerSize) ? PositiveFlexibility : NegativeFlexibility;
         InflexibleFlexItemSize inflexibleItems;
         childSizes.reserveCapacity(orderedChildren.size());
-        while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems, childSizes)) {
+        while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeSpace, remainingFreeSpace, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, inflexibleItems, childSizes)) {
             ASSERT(totalFlexGrow >= 0 && totalWeightedFlexShrink >= 0);
             ASSERT(inflexibleItems.size() > 0);
         }
 
-        layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, availableFreeSpace, relayoutChildren, layoutScope, lineContexts);
+        layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, remainingFreeSpace, relayoutChildren, layoutScope, lineContexts);
     }
     if (hasLineIfEmpty()) {
         // Even if computeNextFlexLine returns true, the flexbox might not have
@@ -927,11 +932,11 @@
     return std::max(childSize, minExtent);
 }
 
-bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayoutChildren)
+bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayoutChildren)
 {
     orderedChildren.clear();
     sumFlexBaseSize = 0;
-    totalFlexGrow = totalWeightedFlexShrink = 0;
+    totalFlexGrow = totalFlexShrink = totalWeightedFlexShrink = 0;
     sumHypotheticalMainSize = 0;
 
     if (!m_orderIterator.currentChild())
@@ -971,19 +976,21 @@
         lineHasInFlowItem  = true;
         sumFlexBaseSize += childOuterFlexBaseSize;
         totalFlexGrow += child->style()->flexGrow();
+        totalFlexShrink += child->style()->flexShrink();
         totalWeightedFlexShrink += child->style()->flexShrink() * childInnerFlexBaseSize;
         sumHypotheticalMainSize += childHypotheticalMainSize;
     }
     return true;
 }
 
-void LayoutFlexibleBox::freezeViolations(const Vector<Violation>& violations, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems)
+void LayoutFlexibleBox::freezeViolations(const Vector<Violation>& violations, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems)
 {
     for (size_t i = 0; i < violations.size(); ++i) {
         LayoutBox* child = violations[i].child;
         LayoutUnit childSize = violations[i].childSize;
         availableFreeSpace -= childSize - violations[i].childInnerFlexBaseSize;
         totalFlexGrow -= child->style()->flexGrow();
+        totalFlexShrink -= child->style()->flexShrink();
         totalWeightedFlexShrink -= child->style()->flexShrink() * violations[i].childInnerFlexBaseSize;
         // totalWeightedFlexShrink can be negative when we exceed the precision of a double when we initially
         // calcuate totalWeightedFlexShrink. We then subtract each child's weighted flex shrink with full precision,
@@ -994,13 +1001,21 @@
 }
 
 // Returns true if we successfully ran the algorithm and sized the flex items.
-bool LayoutFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, Vector<LayoutUnit, 16>& childSizes)
+bool LayoutFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit availableFreeSpace, LayoutUnit& remainingFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, Vector<LayoutUnit, 16>& childSizes)
 {
     childSizes.resize(0);
     LayoutUnit totalViolation = 0;
     LayoutUnit usedFreeSpace = 0;
     Vector<Violation> minViolations;
     Vector<Violation> maxViolations;
+
+    double sumFlexFactors = (flexSign == PositiveFlexibility) ? totalFlexGrow : totalFlexShrink;
+    if (sumFlexFactors > 0 && sumFlexFactors < 1) {
+        LayoutUnit fractional = availableFreeSpace * sumFlexFactors;
+        if (fractional.abs() < remainingFreeSpace.abs())
+            remainingFreeSpace = fractional;
+    }
+
     for (size_t i = 0; i < children.size(); ++i) {
         LayoutBox* child = children[i];
         if (child->isOutOfFlowPositioned()) {
@@ -1014,13 +1029,10 @@
             LayoutUnit childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild(*child);
             LayoutUnit childSize = childInnerFlexBaseSize;
             double extraSpace = 0;
-            if (availableFreeSpace > 0 && totalFlexGrow > 0 && flexSign == PositiveFlexibility && std::isfinite(totalFlexGrow)) {
-                if (totalFlexGrow < 1)
-                    extraSpace = availableFreeSpace * child->style()->flexGrow();
-                else
-                    extraSpace = availableFreeSpace * child->style()->flexGrow() / totalFlexGrow;
-            } else if (availableFreeSpace < 0 && totalWeightedFlexShrink > 0 && flexSign == NegativeFlexibility && std::isfinite(totalWeightedFlexShrink) && child->style()->flexShrink()) {
-                extraSpace = availableFreeSpace * child->style()->flexShrink() * childInnerFlexBaseSize / totalWeightedFlexShrink;
+            if (remainingFreeSpace > 0 && totalFlexGrow > 0 && flexSign == PositiveFlexibility && std::isfinite(totalFlexGrow)) {
+                extraSpace = remainingFreeSpace * child->style()->flexGrow() / totalFlexGrow;
+            } else if (remainingFreeSpace < 0 && totalWeightedFlexShrink > 0 && flexSign == NegativeFlexibility && std::isfinite(totalWeightedFlexShrink) && child->style()->flexShrink()) {
+                extraSpace = remainingFreeSpace * child->style()->flexShrink() * childInnerFlexBaseSize / totalWeightedFlexShrink;
             }
             if (std::isfinite(extraSpace))
                 childSize += LayoutUnit::fromFloatRound(extraSpace);
@@ -1040,9 +1052,9 @@
     }
 
     if (totalViolation)
-        freezeViolations(totalViolation < 0 ? maxViolations : minViolations, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems);
+        freezeViolations(totalViolation < 0 ? maxViolations : minViolations, remainingFreeSpace, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, inflexibleItems);
     else
-        availableFreeSpace -= usedFreeSpace;
+        remainingFreeSpace -= usedFreeSpace;
 
     return !totalViolation;
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h
index e404192..a4948ca8 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h
+++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h
@@ -155,10 +155,10 @@
     void prepareOrderIteratorAndMargins();
     LayoutUnit adjustChildSizeForMinAndMax(const LayoutBox& child, LayoutUnit childSize);
     // The hypothetical main size of an item is the flex base size clamped according to its min and max main size properties
-    bool computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayoutChildren);
+    bool computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayoutChildren);
 
-    bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, Vector<LayoutUnit, 16>& childSizes);
-    void freezeViolations(const Vector<Violation>&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&);
+    bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit availableFreeSpace, LayoutUnit& remainingFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, Vector<LayoutUnit, 16>& childSizes);
+    void freezeViolations(const Vector<Violation>&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, InflexibleFlexItemSize&);
 
     void resetAutoMarginsAndLogicalTopInCrossAxis(LayoutBox& child);
     void setOverrideMainAxisSizeForChild(LayoutBox& child, LayoutUnit childPreferredSize);
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index 3b32e5d..5a654f7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -1105,15 +1105,13 @@
 
 void LayoutGrid::insertItemIntoGrid(LayoutBox& child, const GridCoordinate& coordinate)
 {
+    RELEASE_ASSERT(coordinate.rows.isDefinite() && coordinate.columns.isDefinite());
     ensureGridSize(coordinate.rows.resolvedFinalPosition().toInt(), coordinate.columns.resolvedFinalPosition().toInt());
 
     for (GridSpan::iterator row = coordinate.rows.begin(); row != coordinate.rows.end(); ++row) {
         for (GridSpan::iterator column = coordinate.columns.begin(); column != coordinate.columns.end(); ++column)
             m_grid[row.toInt()][column.toInt()].append(&child);
     }
-
-    RELEASE_ASSERT(!m_gridItemCoordinate.contains(&child));
-    m_gridItemCoordinate.set(&child, coordinate);
 }
 
 void LayoutGrid::placeItemsOnGrid()
@@ -1134,17 +1132,16 @@
         if (child->isOutOfFlowPositioned())
             continue;
 
-        GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForRows);
-        GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForColumns);
-        if (!rowPositions.isDefinite() || !columnPositions.isDefinite()) {
-            GridSpan majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? columnPositions : rowPositions;
+        GridCoordinate coordinate = cachedGridCoordinate(*child);
+        if (!coordinate.rows.isDefinite() || !coordinate.columns.isDefinite()) {
+            GridSpan majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? coordinate.columns : coordinate.rows;
             if (!majorAxisPositions.isDefinite())
                 autoMajorAxisAutoGridItems.append(child);
             else
                 specifiedMajorAxisAutoGridItems.append(child);
             continue;
         }
-        insertItemIntoGrid(*child, GridCoordinate(rowPositions, columnPositions));
+        insertItemIntoGrid(*child, coordinate);
     }
 
     ASSERT(gridRowCount() >= GridResolvedPosition::explicitGridRowCount(*style()));
@@ -1154,6 +1151,16 @@
     placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems);
 
     m_grid.shrinkToFit();
+
+#if ENABLE(ASSERT)
+    for (LayoutBox* child = m_orderIterator.first(); child; child = m_orderIterator.next()) {
+        if (child->isOutOfFlowPositioned())
+            continue;
+
+        GridCoordinate coordinate = cachedGridCoordinate(*child);
+        ASSERT(coordinate.rows.isDefinite() && coordinate.columns.isDefinite());
+    }
+#endif
 }
 
 void LayoutGrid::populateExplicitGridAndOrderIterator()
@@ -1175,6 +1182,7 @@
         // This function bypasses the cache (cachedGridCoordinate()) as it is used to build it.
         GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForRows);
         GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForColumns);
+        m_gridItemCoordinate.set(child, GridCoordinate(rowPositions, columnPositions));
 
         // |positions| is 0 if we need to run the auto-placement algorithm.
         if (rowPositions.isDefinite()) {
@@ -1218,7 +1226,9 @@
     HashMap<unsigned, unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> minorAxisCursors;
 
     for (const auto& autoGridItem : autoGridItems) {
-        GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *autoGridItem, autoPlacementMajorAxisDirection());
+        GridSpan majorAxisPositions = cachedGridSpan(*autoGridItem, autoPlacementMajorAxisDirection());
+        ASSERT(majorAxisPositions.isDefinite());
+        ASSERT(!cachedGridSpan(*autoGridItem, autoPlacementMinorAxisDirection()).isDefinite());
         GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *autoGridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
         unsigned majorAxisInitialPosition = majorAxisPositions.resolvedInitialPosition().toInt();
 
@@ -1226,6 +1236,8 @@
         OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions.integerSpan(), minorAxisPositions.integerSpan());
         if (!emptyGridArea)
             emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*autoGridItem, autoPlacementMajorAxisDirection(), majorAxisPositions);
+
+        m_gridItemCoordinate.set(autoGridItem, *emptyGridArea);
         insertItemIntoGrid(*autoGridItem, *emptyGridArea);
 
         if (!isGridAutoFlowDense)
@@ -1251,8 +1263,8 @@
 
 void LayoutGrid::placeAutoMajorAxisItemOnGrid(LayoutBox& gridItem, std::pair<size_t, size_t>& autoPlacementCursor)
 {
-    GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), gridItem, autoPlacementMinorAxisDirection());
-    ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), gridItem, autoPlacementMajorAxisDirection()).isDefinite());
+    GridSpan minorAxisPositions = cachedGridSpan(gridItem, autoPlacementMinorAxisDirection());
+    ASSERT(!cachedGridSpan(gridItem, autoPlacementMajorAxisDirection()).isDefinite());
     GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), gridItem, autoPlacementMajorAxisDirection(), GridResolvedPosition(0));
 
     const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForColumns) ? gridColumnCount() : gridRowCount();
@@ -1299,6 +1311,7 @@
             emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), minorAxisPositions);
     }
 
+    m_gridItemCoordinate.set(&gridItem, *emptyGridArea);
     insertItemIntoGrid(gridItem, *emptyGridArea);
     // Move auto-placement cursor to the new position.
     autoPlacementCursor.first = emptyGridArea->rows.resolvedInitialPosition().toInt();
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationGroupPreviewUI.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationGroupPreviewUI.js
index 432501a4..f9b4d12 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationGroupPreviewUI.js
+++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationGroupPreviewUI.js
@@ -61,7 +61,7 @@
         this._svg.removeChildren();
         var maxToShow = 10;
         var numberOfAnimations = Math.min(this._model.animations().length, maxToShow);
-        var timeToPixelRatio = 100 / Math.max(this._groupDuration(), 300);
+        var timeToPixelRatio = 100 / Math.max(this._groupDuration(), 750);
         for (var i = 0; i < numberOfAnimations; i++) {
             var effect = this._model.animations()[i].source();
             var line = this._svg.createSVGChild("line");
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js
index 03253a3..0db79cd3 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js
@@ -102,7 +102,7 @@
 
         if (!matchedGroup) {
             this._animationGroups.set(incomingGroup.id(), incomingGroup);
-            this._screenshotCapture.captureScreenshots(incomingGroup._finiteDuration(), incomingGroup._screenshots);
+            this._screenshotCapture.captureScreenshots(incomingGroup.finiteDuration(), incomingGroup._screenshots);
         }
         this.dispatchEventToListeners(WebInspector.AnimationModel.Events.AnimationGroupStarted, matchedGroup || incomingGroup);
         return !!matchedGroup;
@@ -314,7 +314,7 @@
      */
     _finiteDuration: function()
     {
-        var iterations = this.source().iterations() ? this.source().iterations() : 3;
+        var iterations = Math.min(this.source().iterations(), 3);
         return this.source().delay() + this.source().duration() * iterations;
     },
 
@@ -714,7 +714,7 @@
     /**
      * @return {number}
      */
-    _finiteDuration: function()
+    finiteDuration: function()
     {
         var maxDuration = 0;
         for (var i = 0; i < this._animations.length; ++i)
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js
index 3102f8e..3dc4cbef 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js
+++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js
@@ -25,6 +25,7 @@
     this._timelineControlsWidth = 150;
     /** @type {!Map.<!DOMAgent.BackendNodeId, !WebInspector.AnimationTimeline.NodeUI>} */
     this._nodesMap = new Map();
+    this._uiAnimations = [];
     this._groupBuffer = [];
     this._groupBufferSize = 8;
     /** @type {!Map.<!WebInspector.AnimationModel.AnimationGroup, !WebInspector.AnimationGroupPreviewUI>} */
@@ -34,6 +35,7 @@
     this._animationsMap = new Map();
     WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
     WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Page);
+    WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this._nodeChanged, this);
 }
 
 WebInspector.AnimationTimeline.GlobalPlaybackRates = [1, 0.25, 0.1];
@@ -312,23 +314,13 @@
         this.scheduleRedraw();
     },
 
-    /**
-     * @return {number|undefined}
-     */
-    startTime: function()
-    {
-        return this._startTime;
-    },
-
     _clearTimeline: function()
     {
         this._nodesMap.clear();
         this._animationsMap.clear();
         this._animationsContainer.removeChildren();
         this._duration = this._defaultDuration();
-        delete this._startTime;
         this._timelineScrubber.classList.add("hidden");
-
     },
 
     _reset: function()
@@ -435,6 +427,7 @@
         this._selectedGroup = group;
         this._previewMap.forEach(applySelectionClass, this);
         this._clearTimeline();
+        this.setDuration(Math.max(500, group.finiteDuration() + 100));
         for (var anim of group.animations())
             this._addAnimation(anim);
         this.scheduleRedraw();
@@ -454,24 +447,22 @@
          */
         function nodeResolved(node)
         {
-            if (!node)
-                return;
+            nodeUI.nodeResolved(node);
             uiAnimation.setNode(node);
-            node[this._symbol] = nodeUI;
+            if (node)
+                node[this._symbol] = nodeUI;
         }
 
-        this._resizeWindow(animation);
-
         var nodeUI = this._nodesMap.get(animation.source().backendNodeId());
         if (!nodeUI) {
             nodeUI = new WebInspector.AnimationTimeline.NodeUI(animation.source());
             this._animationsContainer.appendChild(nodeUI.element);
             this._nodesMap.set(animation.source().backendNodeId(), nodeUI);
         }
-        var nodeRow = nodeUI.findRow(animation);
-        var uiAnimation = new WebInspector.AnimationUI(animation, this, nodeRow.element);
+        var nodeRow = nodeUI.createNewRow();
+        var uiAnimation = new WebInspector.AnimationUI(animation, this, nodeRow);
         animation.source().deferredNode().resolve(nodeResolved.bind(this));
-        nodeRow.animations.push(uiAnimation);
+        this._uiAnimations.push(uiAnimation);
         this._animationsMap.set(animation.id(), animation);
     },
 
@@ -525,8 +516,8 @@
     _redraw: function(timestamp)
     {
         delete this._redrawing;
-        for (var nodeUI of this._nodesMap.values())
-            nodeUI.redraw();
+        for (var ui of this._uiAnimations)
+            ui.redraw();
         this._renderGrid();
     },
 
@@ -553,15 +544,13 @@
     _resizeWindow: function(animation)
     {
         var resized = false;
-        if (!this._startTime)
-            this._startTime = animation.startTime();
 
         // This shows at most 3 iterations
-        var duration = animation.source().duration() * Math.min(3, animation.source().iterations());
-        var requiredDuration = animation.startTime() + animation.source().delay() + duration + animation.source().endDelay() - this.startTime();
-        if (requiredDuration > this._duration * 0.8) {
+        var duration = animation.source().duration() * Math.min(2, animation.source().iterations());
+        var requiredDuration = animation.source().delay() + duration + animation.source().endDelay();
+        if (requiredDuration > this._duration) {
             resized = true;
-            this._duration = requiredDuration * 1.5;
+            this._duration = requiredDuration + 200;
         }
         return resized;
     },
@@ -689,72 +678,32 @@
  */
 WebInspector.AnimationTimeline.NodeUI = function(animationEffect)
 {
-    /**
-     * @param {?WebInspector.DOMNode} node
-     * @this {WebInspector.AnimationTimeline.NodeUI}
-     */
-    function nodeResolved(node)
-    {
-        if (!node)
-            return;
-        this._node = node;
-        this._nodeChanged();
-        this._description.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node));
-    }
-
-    this._rows = [];
     this.element = createElementWithClass("div", "animation-node-row");
     this._description = this.element.createChild("div", "animation-node-description");
-    animationEffect.deferredNode().resolve(nodeResolved.bind(this));
     this._timelineElement = this.element.createChild("div", "animation-node-timeline");
 }
 
-/** @typedef {{element: !Element, animations: !Array<!WebInspector.AnimationUI>}} */
-WebInspector.AnimationTimeline.NodeRow;
-
 WebInspector.AnimationTimeline.NodeUI.prototype = {
     /**
-     * @param {!WebInspector.AnimationModel.Animation} animation
-     * @return {!WebInspector.AnimationTimeline.NodeRow}
+     * @param {?WebInspector.DOMNode} node
      */
-    findRow: function(animation)
+    nodeResolved: function(node)
     {
-        // Check if it can fit into an existing row
-        var existingRow = this._collapsibleIntoRow(animation);
-        if (existingRow)
-            return existingRow;
-
-        // Create new row
-        var container = this._timelineElement.createChild("div", "animation-timeline-row");
-        var nodeRow = {element: container, animations: []};
-        this._rows.push(nodeRow);
-        return nodeRow;
-    },
-
-    redraw: function()
-    {
-        for (var nodeRow of this._rows) {
-            for (var ui of nodeRow.animations)
-                ui.redraw();
+        if (!node) {
+            this._description.createTextChild(WebInspector.UIString("<node>"));
+            return;
         }
+        this._node = node;
+        this._nodeChanged();
+        this._description.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node));
     },
 
     /**
-     * @param {!WebInspector.AnimationModel.Animation} animation
-     * @return {?WebInspector.AnimationTimeline.NodeRow}
+     * @return {!Element}
      */
-    _collapsibleIntoRow: function(animation)
+    createNewRow: function()
     {
-        if (animation.endTime() === Infinity)
-            return null;
-        for (var nodeRow of this._rows) {
-            var overlap = false;
-            for (var ui of nodeRow.animations)
-                overlap |= animation.overlaps(ui.animation());
-            if (!overlap)
-                return nodeRow;
-        }
-        return null;
+        return this._timelineElement.createChild("div", "animation-timeline-row");
     },
 
     nodeRemoved: function()
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js
index 1e587d3..68010e0 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js
+++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js
@@ -195,15 +195,13 @@
     redraw: function()
     {
         var durationWithDelay = this._delay() + this._duration() * this._animation.source().iterations() + this._animation.source().endDelay();
-        var leftMargin = ((this._animation.startTime() - this._timeline.startTime()) * this._timeline.pixelMsRatio());
-        var maxWidth = this._timeline.width() - WebInspector.AnimationUI.Options.AnimationMargin - leftMargin;
+        var maxWidth = this._timeline.width() - WebInspector.AnimationUI.Options.AnimationMargin;
 
         this._svg.classList.toggle("animation-ui-canceled", this._animation.playState() === "idle");
         this._svg.setAttribute("width", (maxWidth + 2 * WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2));
-        this._svg.style.transform = "translateX(" + leftMargin.toFixed(2)  + "px)";
         this._activeIntervalGroup.style.transform = "translateX(" + (this._delay() * this._timeline.pixelMsRatio()).toFixed(2) + "px)";
 
-        this._nameElement.style.transform = "translateX(" + (leftMargin + this._delay() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2) + "px)";
+        this._nameElement.style.transform = "translateX(" + (this._delay() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2) + "px)";
         this._nameElement.style.width = (this._duration() * this._timeline.pixelMsRatio()).toFixed(2) + "px";
         this._drawDelayLine(this._svg);
 
@@ -327,7 +325,7 @@
     _mouseMove: function (event)
     {
         this._movementInMs = (event.clientX - this._downMouseX) / this._timeline.pixelMsRatio();
-        if (this._animation.startTime() + this._delay() + this._duration() - this._timeline.startTime() > this._timeline.duration() * 0.8)
+        if (this._delay() + this._duration() > this._timeline.duration() * 0.8)
             this._timeline.setDuration(this._timeline.duration() * 1.2);
         this.redraw();
     },
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css b/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css
index fb207f64..9a02b3d1 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css
+++ b/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css
@@ -86,7 +86,6 @@
     text-align: center;
     margin-left: -8px;
     white-space: nowrap;
-    min-width: 50px;
 }
 
 .animation-timeline-toolbar-container {
diff --git a/third_party/WebKit/Source/devtools/front_end/components/domUtils.css b/third_party/WebKit/Source/devtools/front_end/components/domUtils.css
index 79e2544..09397a03 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/domUtils.css
+++ b/third_party/WebKit/Source/devtools/front_end/components/domUtils.css
@@ -11,6 +11,7 @@
 .node-link {
     cursor: pointer;
     display: inline;
+    pointer-events: auto;
 }
 
 .stack-preview-async-description {
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
index 1b99a6d..3927cbc 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
@@ -618,8 +618,6 @@
     {
         if (typeof b === "string")
             b = createTextNode(b);
-        else if (b.shadowRoot)
-            b = createTextNode(b.shadowRoot.lastChild.textContent);
         element.appendChild(b);
     }
     String.format(WebInspector.UIString(format), substitutions, formatters, initialValue, append);
diff --git a/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.cpp b/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.cpp
index 41bf1f2fb..9a9acdb0 100644
--- a/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.cpp
+++ b/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.cpp
@@ -46,7 +46,7 @@
 {
 }
 
-PassRefPtr<EncodedFormData> PasswordCredential::encodeFormData() const
+PassRefPtr<EncodedFormData> PasswordCredential::encodeFormData(String& contentType) const
 {
     if (m_additionalData.isURLSearchParams()) {
         // If |additionalData| is a 'URLSearchParams' object, build a urlencoded response.
@@ -57,6 +57,8 @@
         params->append(idName(), id());
         params->append(passwordName(), password());
 
+        contentType = AtomicString("application/x-www-form-urlencoded;charset=UTF-8", AtomicString::ConstructFromLiteral);
+
         return params->encodeFormData();
     }
 
@@ -74,7 +76,9 @@
     formData->append(idName(), id());
     formData->append(passwordName(), password());
 
-    return formData->encodeMultiPartFormData();
+    RefPtr<EncodedFormData> encodedData = formData->encodeMultiPartFormData();
+    contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + encodedData->boundary().data();
+    return encodedData.release();
 }
 
 const String& PasswordCredential::password() const
diff --git a/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.h b/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.h
index 38ac8d7..c34b11a 100644
--- a/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.h
+++ b/third_party/WebKit/Source/modules/credentialmanager/PasswordCredential.h
@@ -39,7 +39,7 @@
     void additionalData(CredentialPostBodyType& out) const { out = m_additionalData; }
 
     // Internal methods
-    PassRefPtr<EncodedFormData> encodeFormData() const;
+    PassRefPtr<EncodedFormData> encodeFormData(String& contentType) const;
     const String& password() const;
     DECLARE_VIRTUAL_TRACE();
 
diff --git a/third_party/WebKit/Source/modules/fetch/RequestInit.cpp b/third_party/WebKit/Source/modules/fetch/RequestInit.cpp
index a356d26..dd14ee8c 100644
--- a/third_party/WebKit/Source/modules/fetch/RequestInit.cpp
+++ b/third_party/WebKit/Source/modules/fetch/RequestInit.cpp
@@ -92,11 +92,7 @@
         isCredentialRequest = true;
         PasswordCredential* credential = V8PasswordCredential::toImpl(v8::Local<v8::Object>::Cast(v8Body));
 
-        RefPtr<EncodedFormData> encodedData = credential->encodeFormData();
-        if (encodedData->boundary().isEmpty())
-            contentType = AtomicString("application/x-www-form-urlencoded;charset=UTF-8", AtomicString::ConstructFromLiteral);
-        else
-            contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + encodedData->boundary().data();
+        RefPtr<EncodedFormData> encodedData = credential->encodeFormData(contentType);
         body = FetchFormDataConsumerHandle::create(context, encodedData.release());
     } else if (v8Body->IsString()) {
         contentType = "text/plain;charset=UTF-8";
diff --git a/third_party/WebKit/Source/modules/vr/PositionSensorVRDevice.cpp b/third_party/WebKit/Source/modules/vr/PositionSensorVRDevice.cpp
index d36b1fa..083f162e 100644
--- a/third_party/WebKit/Source/modules/vr/PositionSensorVRDevice.cpp
+++ b/third_party/WebKit/Source/modules/vr/PositionSensorVRDevice.cpp
@@ -17,13 +17,12 @@
 
 VRPositionState* PositionSensorVRDevice::getState()
 {
-    // FIXME: This value should be stable for the duration of a requestAnimationFrame callback
     return hardwareUnit()->getSensorState();
 }
 
 VRPositionState* PositionSensorVRDevice::getImmediateState()
 {
-    return hardwareUnit()->getSensorState();
+    return hardwareUnit()->getImmediateSensorState(false);
 }
 
 void PositionSensorVRDevice::resetSensor()
diff --git a/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp b/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp
index ce9a42e..8c39e87d 100644
--- a/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp
+++ b/third_party/WebKit/Source/modules/vr/VREyeParameters.cpp
@@ -14,7 +14,7 @@
     point->setX(vec.x);
     point->setY(vec.y);
     point->setZ(vec.z);
-    point->setW(0.0);
+    point->setW(1.0);
 }
 
 } // namespace
diff --git a/third_party/WebKit/Source/modules/vr/VRHardwareUnit.cpp b/third_party/WebKit/Source/modules/vr/VRHardwareUnit.cpp
index f463332..c01614f 100644
--- a/third_party/WebKit/Source/modules/vr/VRHardwareUnit.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRHardwareUnit.cpp
@@ -18,12 +18,15 @@
     : m_nextDeviceId(1)
     , m_frameIndex(0)
     , m_navigatorVRDevice(navigatorVRDevice)
+    , m_canUpdatePositionState(true)
 {
     m_positionState = VRPositionState::create();
 }
 
 VRHardwareUnit::~VRHardwareUnit()
 {
+    if (!m_canUpdatePositionState)
+        Platform::current()->currentThread()->removeTaskObserver(this);
 }
 
 void VRHardwareUnit::updateFromWebVRDevice(const WebVRDevice& device)
@@ -64,11 +67,35 @@
 
 VRPositionState* VRHardwareUnit::getSensorState()
 {
+    if (m_canUpdatePositionState) {
+        m_positionState = getImmediateSensorState(true);
+        Platform::current()->currentThread()->addTaskObserver(this);
+        m_canUpdatePositionState = false;
+    }
+
+    return m_positionState;
+}
+
+VRPositionState* VRHardwareUnit::getImmediateSensorState(bool updateFrameIndex)
+{
     WebHMDSensorState state;
     controller()->getSensorState(m_index, state);
-    m_positionState->setState(state);
-    m_frameIndex = state.frameIndex;
-    return m_positionState;
+    if (updateFrameIndex)
+        m_frameIndex = state.frameIndex;
+
+    VRPositionState* immediatePositionState = VRPositionState::create();
+    immediatePositionState->setState(state);
+    return immediatePositionState;
+}
+
+
+void VRHardwareUnit::didProcessTask()
+{
+    // State should be stable until control is returned to the user agent.
+    if (!m_canUpdatePositionState) {
+        Platform::current()->currentThread()->removeTaskObserver(this);
+        m_canUpdatePositionState = true;
+    }
 }
 
 DEFINE_TRACE(VRHardwareUnit)
diff --git a/third_party/WebKit/Source/modules/vr/VRHardwareUnit.h b/third_party/WebKit/Source/modules/vr/VRHardwareUnit.h
index 62a4cbee..996513d 100644
--- a/third_party/WebKit/Source/modules/vr/VRHardwareUnit.h
+++ b/third_party/WebKit/Source/modules/vr/VRHardwareUnit.h
@@ -8,6 +8,7 @@
 #include "modules/vr/VRFieldOfView.h"
 #include "modules/vr/VRPositionState.h"
 #include "platform/heap/Handle.h"
+#include "public/platform/WebThread.h"
 #include "wtf/text/WTFString.h"
 
 namespace blink {
@@ -24,7 +25,7 @@
     VREyeNone,
 };
 
-class VRHardwareUnit : public GarbageCollectedFinalized<VRHardwareUnit> {
+class VRHardwareUnit : public GarbageCollectedFinalized<VRHardwareUnit>, public WebThread::TaskObserver {
 public:
     explicit VRHardwareUnit(NavigatorVRDevice*);
     virtual ~VRHardwareUnit();
@@ -42,6 +43,7 @@
 
     // VRController queries
     VRPositionState* getSensorState();
+    VRPositionState* getImmediateSensorState(bool updateFrameIndex);
 
     HMDVRDevice* hmd() const { return m_hmd; }
     PositionSensorVRDevice* positionSensor() const { return m_positionSensor; }
@@ -49,6 +51,10 @@
     DECLARE_VIRTUAL_TRACE();
 
 private:
+    // TaskObserver implementation.
+    void didProcessTask() override;
+    void willProcessTask() override { }
+
     unsigned m_index;
     String m_hardwareUnitId;
     unsigned m_nextDeviceId;
@@ -57,6 +63,7 @@
 
     Member<NavigatorVRDevice> m_navigatorVRDevice;
     Member<VRPositionState> m_positionState;
+    bool m_canUpdatePositionState;
 
     // Device types
     Member<HMDVRDevice> m_hmd;
diff --git a/third_party/WebKit/Source/modules/vr/VRPositionState.cpp b/third_party/WebKit/Source/modules/vr/VRPositionState.cpp
index 0a1738b8..8c7a956 100644
--- a/third_party/WebKit/Source/modules/vr/VRPositionState.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRPositionState.cpp
@@ -18,7 +18,7 @@
 DOMPoint* vecToDomPoint(const WebVRVector3& vec, bool valid)
 {
     if (valid)
-        return DOMPoint::create(vec.x, vec.y, vec.z, 0.0);
+        return DOMPoint::create(vec.x, vec.y, vec.z, 1.0);
     return nullptr;
 }
 
diff --git a/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteFileSystemPosix.cpp b/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteFileSystemPosix.cpp
index a1921a0..fda7d6c 100644
--- a/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteFileSystemPosix.cpp
+++ b/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteFileSystemPosix.cpp
@@ -143,17 +143,10 @@
 int chromiumOpenInternal(sqlite3_vfs* vfs, const char* fileName, sqlite3_file* id, int desiredFlags, int* usedFlags)
 {
     chromium_sqlite3_initialize_unix_sqlite3_file(id);
-    int fd = -1;
-    int result = chromium_sqlite3_get_reusable_file_handle(id, fileName, desiredFlags, &fd);
-    if (result != SQLITE_OK)
-        return result;
-
-    if (fd < 0) {
-        fd = Platform::current()->databaseOpenFile(String(fileName), desiredFlags);
-        if ((fd < 0) && (desiredFlags & SQLITE_OPEN_READWRITE)) {
-            int newFlags = (desiredFlags & ~(SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)) | SQLITE_OPEN_READONLY;
-            fd = Platform::current()->databaseOpenFile(String(fileName), newFlags);
-        }
+    int fd = Platform::current()->databaseOpenFile(String(fileName), desiredFlags);
+    if ((fd < 0) && (desiredFlags & SQLITE_OPEN_READWRITE)) {
+        int newFlags = (desiredFlags & ~(SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)) | SQLITE_OPEN_READONLY;
+        fd = Platform::current()->databaseOpenFile(String(fileName), newFlags);
     }
     if (fd < 0) {
         chromium_sqlite3_destroy_reusable_file_handle(id);
@@ -170,7 +163,7 @@
     int fileType = desiredFlags & 0x00007F00;
     int noLock = (fileType != SQLITE_OPEN_MAIN_DB);
     sqlite3_vfs* wrappedVfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
-    result = chromium_sqlite3_fill_in_unix_sqlite3_file(wrappedVfs, fd, -1, id, fileName, noLock);
+    int result = chromium_sqlite3_fill_in_unix_sqlite3_file(wrappedVfs, fd, -1, id, fileName, noLock);
     if (result != SQLITE_OK)
         chromium_sqlite3_destroy_reusable_file_handle(id);
     return result;
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index 0a5053b3..2e4b21ed 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -49,7 +49,6 @@
 CSSGridLayout status=experimental
 CSSIndependentTransformProperties status=experimental
 CSSMaskSourceType status=experimental
-CSSMotionPath status=stable
 CSSOMSmoothScroll status=experimental
 CSSStickyPosition
 CSSTouchActionPanDirections status=experimental
diff --git a/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm b/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
index 666c28e..39e1e14 100644
--- a/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
+++ b/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
@@ -35,15 +35,15 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/fonts/FontDescription.h"
 #include "platform/fonts/FontFaceCreationParams.h"
-#include  "platform/fonts/FontPlatformData.h"
+#include "platform/fonts/FontPlatformData.h"
 #include "platform/fonts/SimpleFontData.h"
 #include "platform/fonts/mac/FontFamilyMatcherMac.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebTaskRunner.h"
 #include "public/platform/WebTraceLocation.h"
-#include <wtf/Functional.h>
-#include <wtf/MainThread.h>
-#include <wtf/StdLibExtras.h>
+#include "wtf/Functional.h"
+#include "wtf/MainThread.h"
+#include "wtf/StdLibExtras.h"
 
 // Forward declare Mac SPIs.
 // Request for public API: rdar://13803570
diff --git a/third_party/WebKit/Source/platform/fonts/mac/FontFamilyMatcherMac.mm b/third_party/WebKit/Source/platform/fonts/mac/FontFamilyMatcherMac.mm
index d71d4b2..8a0bb29 100644
--- a/third_party/WebKit/Source/platform/fonts/mac/FontFamilyMatcherMac.mm
+++ b/third_party/WebKit/Source/platform/fonts/mac/FontFamilyMatcherMac.mm
@@ -33,12 +33,11 @@
 #import <AppKit/AppKit.h>
 #import <Foundation/Foundation.h>
 #import <math.h>
-#import <wtf/HashSet.h>
-#import <wtf/text/AtomicStringHash.h>
-
 #include "platform/fonts/FontTraits.h"
 #include "platform/LayoutTestSupport.h"
 #include "platform/mac/VersionUtilMac.h"
+#import "wtf/HashSet.h"
+#import "wtf/text/AtomicStringHash.h"
 
  @interface NSFont (YosemiteAdditions)
  + (NSFont*)systemFontOfSize:(CGFloat)size weight:(CGFloat)weight;
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
index 5cf79cc4..256190d7 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -116,7 +116,7 @@
     , m_paintCount(0)
     , m_contentsLayer(0)
     , m_contentsLayerId(0)
-    , m_scrollableArea(0)
+    , m_scrollableArea(nullptr)
     , m_3dRenderingContext(0)
 {
 #if ENABLE(ASSERT)
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
index de584cc..371b1f1 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -368,8 +368,7 @@
 
     OwnPtr<ContentLayerDelegate> m_contentLayerDelegate;
 
-    GC_PLUGIN_IGNORE("509911")
-    ScrollableArea* m_scrollableArea;
+    RawPtrWillBeWeakPersistent<ScrollableArea> m_scrollableArea;
     GraphicsLayerDebugInfo m_debugInfo;
     int m_3dRenderingContext;
 
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.cpp b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
index 10b30f8..1364135 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
@@ -177,8 +177,10 @@
 {
     clearFreeLists();
     ASSERT(isConsistentForGC());
-    for (BasePage* page = m_firstPage; page; page = page->next())
+    for (BasePage* page = m_firstPage; page; page = page->next()) {
         page->markAsUnswept();
+        page->invalidateObjectStartBitmap();
+    }
 
     // If a new GC is requested before this thread got around to sweep,
     // ie. due to the thread doing a long running operation, we clear
@@ -191,6 +193,7 @@
     for (BasePage* page = m_firstUnsweptPage; page; previousPage = page, page = page->next()) {
         page->makeConsistentForGC();
         ASSERT(!page->hasBeenSwept());
+        page->invalidateObjectStartBitmap();
     }
     if (previousPage) {
         ASSERT(m_firstUnsweptPage);
@@ -213,6 +216,7 @@
     for (BasePage* page = m_firstUnsweptPage; page; previousPage = page, page = page->next()) {
         page->makeConsistentForMutator();
         page->markAsSwept();
+        page->invalidateObjectStartBitmap();
     }
     if (previousPage) {
         ASSERT(m_firstUnsweptPage);
@@ -508,7 +512,6 @@
     m_freeList.clear();
     size_t freedSize = 0;
     for (NormalPage* page = static_cast<NormalPage*>(m_firstPage); page; page = static_cast<NormalPage*>(page->next())) {
-        page->clearObjectStartBitMap();
         Address startOfGap = page->payload();
         for (Address headerAddress = startOfGap; headerAddress < page->payloadEnd(); ) {
             HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAddress);
@@ -1073,8 +1076,8 @@
 
 NormalPage::NormalPage(PageMemory* storage, BaseHeap* heap)
     : BasePage(storage, heap)
+    , m_objectStartBitMapComputed(false)
 {
-    m_objectStartBitMapComputed = false;
     ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this)));
 }
 
@@ -1110,8 +1113,6 @@
 
 void NormalPage::sweep()
 {
-    clearObjectStartBitMap();
-
     size_t markedObjectSize = 0;
     Address startOfGap = payload();
     for (Address headerAddress = startOfGap; headerAddress < payloadEnd(); ) {
@@ -1266,11 +1267,6 @@
     m_objectStartBitMapComputed = true;
 }
 
-void NormalPage::clearObjectStartBitMap()
-{
-    m_objectStartBitMapComputed = false;
-}
-
 static int numberOfLeadingZeroes(uint8_t byte)
 {
     if (!byte)
@@ -1293,7 +1289,7 @@
 {
     if (address < payload())
         return nullptr;
-    if (!isObjectStartBitMapComputed())
+    if (!m_objectStartBitMapComputed)
         populateObjectStartBitMap();
     size_t objectOffset = address - payload();
     size_t objectStartNumber = objectOffset / allocationGranularity;
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.h b/third_party/WebKit/Source/platform/heap/HeapPage.h
index 7dc892e..b35988a 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.h
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.h
@@ -235,14 +235,14 @@
 #endif
 
     // In 64 bit architectures, we intentionally add 4 byte padding immediately
-    // after the HeapHeaderObject. This is because:
+    // after the HeapObjectHeader. This is because:
     //
-    // | HeapHeaderObject (4 byte) | padding (4 byte) | object payload (8 * n byte) |
+    // | HeapObjectHeader (4 byte) | padding (4 byte) | object payload (8 * n byte) |
     // ^8 byte aligned                                ^8 byte aligned
     //
     // is better than:
     //
-    // | HeapHeaderObject (4 byte) | object payload (8 * n byte) | padding (4 byte) |
+    // | HeapObjectHeader (4 byte) | object payload (8 * n byte) | padding (4 byte) |
     // ^4 byte aligned             ^8 byte aligned               ^4 byte aligned
     //
     // since the former layout aligns both header and payload to 8 byte.
@@ -373,6 +373,7 @@
     virtual void sweep() = 0;
     virtual void makeConsistentForGC() = 0;
     virtual void makeConsistentForMutator() = 0;
+    virtual void invalidateObjectStartBitmap() = 0;
 
 #if defined(ADDRESS_SANITIZER)
     virtual void poisonObjects(BlinkGC::ObjectsToPoison, BlinkGC::Poisoning) = 0;
@@ -457,6 +458,7 @@
     void sweep() override;
     void makeConsistentForGC() override;
     void makeConsistentForMutator() override;
+    void invalidateObjectStartBitmap() override { m_objectStartBitMapComputed = false; }
 #if defined(ADDRESS_SANITIZER)
     void poisonObjects(BlinkGC::ObjectsToPoison, BlinkGC::Poisoning) override;
 #endif
@@ -481,12 +483,10 @@
 
 
     NormalPageHeap* heapForNormalPage();
-    void clearObjectStartBitMap();
 
 private:
     HeapObjectHeader* findHeaderFromAddress(Address);
     void populateObjectStartBitMap();
-    bool isObjectStartBitMapComputed() { return m_objectStartBitMapComputed; }
 
     bool m_objectStartBitMapComputed;
     uint8_t m_objectStartBitMap[reservedForObjectBitMap];
@@ -515,6 +515,7 @@
     void sweep() override;
     void makeConsistentForGC() override;
     void makeConsistentForMutator() override;
+    void invalidateObjectStartBitmap() override { }
 #if defined(ADDRESS_SANITIZER)
     void poisonObjects(BlinkGC::ObjectsToPoison, BlinkGC::Poisoning) override;
 #endif
diff --git a/third_party/WebKit/Source/platform/mac/BlockExceptions.h b/third_party/WebKit/Source/platform/mac/BlockExceptions.h
index 10f80b2..6882ac85f 100644
--- a/third_party/WebKit/Source/platform/mac/BlockExceptions.h
+++ b/third_party/WebKit/Source/platform/mac/BlockExceptions.h
@@ -23,9 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#import <platform/PlatformExport.h>
 #import <Foundation/NSException.h>
-#import <wtf/Assertions.h>
+#import "platform/PlatformExport.h"
+#import "wtf/Assertions.h"
 
 PLATFORM_EXPORT NO_RETURN_DUE_TO_ASSERT void ReportBlockedObjCException(NSException *);
 
diff --git a/third_party/WebKit/Source/platform/mac/BlockExceptions.mm b/third_party/WebKit/Source/platform/mac/BlockExceptions.mm
index af3b879c..bb8d32ce 100644
--- a/third_party/WebKit/Source/platform/mac/BlockExceptions.mm
+++ b/third_party/WebKit/Source/platform/mac/BlockExceptions.mm
@@ -26,7 +26,7 @@
 #import "config.h"
 #import "platform/mac/BlockExceptions.h"
 
-#import <wtf/Assertions.h>
+#import "wtf/Assertions.h"
 
 void ReportBlockedObjCException(NSException *exception)
 {
diff --git a/third_party/WebKit/Source/platform/mac/ColorMac.mm b/third_party/WebKit/Source/platform/mac/ColorMac.mm
index 7a1eef6..2265b45 100644
--- a/third_party/WebKit/Source/platform/mac/ColorMac.mm
+++ b/third_party/WebKit/Source/platform/mac/ColorMac.mm
@@ -26,8 +26,8 @@
 #import "config.h"
 #import "platform/mac/ColorMac.h"
 
-#import <wtf/RetainPtr.h>
-#import <wtf/StdLibExtras.h>
+#import "wtf/RetainPtr.h"
+#import "wtf/StdLibExtras.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/web/WebDevToolsFrontendImpl.h b/third_party/WebKit/Source/web/WebDevToolsFrontendImpl.h
index 2825ab4f..4d9e770f 100644
--- a/third_party/WebKit/Source/web/WebDevToolsFrontendImpl.h
+++ b/third_party/WebKit/Source/web/WebDevToolsFrontendImpl.h
@@ -60,9 +60,7 @@
     void setInjectedScriptForOrigin(const String& origin, const String& source) override;
 
 private:
-    // TODO(Oilpan): Make the lifetime of m_webFrame clear to remove this GC_PLUGIN_IGNORE.
-    GC_PLUGIN_IGNORE("http://crbug.com/509911")
-    WebLocalFrameImpl* m_webFrame;
+    RefPtrWillBePersistent<WebLocalFrameImpl> m_webFrame;
     WebDevToolsFrontendClient* m_client;
     RefPtrWillBePersistent<DevToolsHost> m_devtoolsHost;
     typedef HashMap<String, String> InjectedScriptForOriginMap;
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
index 95730bd..f6a78101 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -1631,6 +1631,11 @@
     return WebLocalFrameImpl::create(scope, client);
 }
 
+WebLocalFrame* WebLocalFrame::createProvisional(WebFrameClient* client, WebRemoteFrame* oldWebFrame, WebSandboxFlags flags, const WebFrameOwnerProperties& frameOwnerProperties)
+{
+    return WebLocalFrameImpl::createProvisional(client, oldWebFrame, flags, frameOwnerProperties);
+}
+
 WebLocalFrameImpl* WebLocalFrameImpl::create(WebTreeScopeType scope, WebFrameClient* client)
 {
     WebLocalFrameImpl* frame = new WebLocalFrameImpl(scope, client);
@@ -1641,6 +1646,45 @@
 #endif
 }
 
+WebLocalFrameImpl* WebLocalFrameImpl::createProvisional(WebFrameClient* client, WebRemoteFrame* oldWebFrame, WebSandboxFlags flags, const WebFrameOwnerProperties& frameOwnerProperties)
+{
+    RefPtrWillBeRawPtr<WebLocalFrameImpl> webFrame = adoptRefWillBeNoop(new WebLocalFrameImpl(oldWebFrame, client));
+    Frame* oldFrame = oldWebFrame->toImplBase()->frame();
+    webFrame->setParent(oldWebFrame->parent());
+    webFrame->setOpener(oldWebFrame->opener());
+    // Note: this *always* temporarily sets a frame owner, even for main frames!
+    // When a core Frame is created with no owner, it attempts to set itself as
+    // the main frame of the Page. However, this is a provisional frame, and may
+    // disappear, so Page::m_mainFrame can't be updated just yet.
+    OwnPtrWillBeRawPtr<FrameOwner> tempOwner = RemoteBridgeFrameOwner::create(nullptr, SandboxNone, WebFrameOwnerProperties());
+    // TODO(dcheng): This block is very similar to initializeCoreFrame. Try to reuse it here.
+    RefPtrWillBeRawPtr<LocalFrame> frame = LocalFrame::create(webFrame->m_frameLoaderClientImpl.get(), oldFrame->host(), tempOwner.get());
+    // Set the name and unique name directly, bypassing any of the normal logic
+    // to calculate unique name.
+    frame->tree().setNameForReplacementFrame(toWebRemoteFrameImpl(oldWebFrame)->frame()->tree().name(), toWebRemoteFrameImpl(oldWebFrame)->frame()->tree().uniqueName());
+    webFrame->setCoreFrame(frame);
+
+    frame->setOwner(oldFrame->owner());
+
+    if (frame->owner() && !frame->owner()->isLocal()) {
+        toRemoteBridgeFrameOwner(frame->owner())->setSandboxFlags(static_cast<SandboxFlags>(flags));
+        // Since a remote frame doesn't get the notifications about frame owner
+        // property modifications, we need to sync up those properties here.
+        webFrame->setFrameOwnerProperties(frameOwnerProperties);
+    }
+
+    // We must call init() after m_frame is assigned because it is referenced
+    // during init(). Note that this may dispatch JS events; the frame may be
+    // detached after init() returns.
+    frame->init();
+#if ENABLE(OILPAN)
+    return webFrame.get();
+#else
+    return webFrame.release().leakRef();
+#endif
+}
+
+
 WebLocalFrameImpl::WebLocalFrameImpl(WebTreeScopeType scope, WebFrameClient* client)
     : WebLocalFrame(scope)
     , m_frameLoaderClientImpl(FrameLoaderClientImpl::create(this))
@@ -1660,6 +1704,11 @@
     frameCount++;
 }
 
+WebLocalFrameImpl::WebLocalFrameImpl(WebRemoteFrame* oldWebFrame, WebFrameClient* client)
+    : WebLocalFrameImpl(oldWebFrame->inShadowTree() ? WebTreeScopeType::Shadow : WebTreeScopeType::Document, client)
+{
+}
+
 WebLocalFrameImpl::~WebLocalFrameImpl()
 {
     // The widget for the frame, if any, must have already been closed.
@@ -1982,38 +2031,6 @@
     frameLoader.stateMachine()->advanceTo(FrameLoaderStateMachine::CommittedMultipleRealLoads);
 }
 
-void WebLocalFrameImpl::initializeToReplaceRemoteFrame(WebRemoteFrame* oldWebFrame, const WebString& name, WebSandboxFlags flags, const WebFrameOwnerProperties& frameOwnerProperties)
-{
-    Frame* oldFrame = oldWebFrame->toImplBase()->frame();
-    // Note: this *always* temporarily sets a frame owner, even for main frames!
-    // When a core Frame is created with no owner, it attempts to set itself as
-    // the main frame of the Page. However, this is a provisional frame, and may
-    // disappear, so Page::m_mainFrame can't be updated just yet.
-    OwnPtrWillBeRawPtr<FrameOwner> tempOwner = RemoteBridgeFrameOwner::create(nullptr, SandboxNone, WebFrameOwnerProperties());
-    RefPtrWillBeRawPtr<LocalFrame> frame = LocalFrame::create(m_frameLoaderClientImpl.get(), oldFrame->host(), tempOwner.get());
-    frame->setOwner(oldFrame->owner());
-    setParent(oldWebFrame->parent());
-    setOpener(oldWebFrame->opener());
-
-    // Set the name and unique name directly.
-    // TODO(creis): Remove |name| and use the oldWebFrame's name.
-    frame->tree().setNameForReplacementFrame(name, toWebRemoteFrameImpl(oldWebFrame)->frame()->tree().uniqueName());
-
-    setCoreFrame(frame);
-
-    if (frame->owner() && !frame->owner()->isLocal()) {
-        toRemoteBridgeFrameOwner(frame->owner())->setSandboxFlags(static_cast<SandboxFlags>(flags));
-        // Since a remote frame doesn't get the notifications about frame owner
-        // property modifications, we need to sync up those properties here.
-        WebLocalFrameImpl::fromFrame(frame.get())->setFrameOwnerProperties(frameOwnerProperties);
-    }
-
-    // We must call init() after m_frame is assigned because it is referenced
-    // during init(). Note that this may dispatch JS events; the frame may be
-    // detached after init() returns.
-    frame->init();
-}
-
 void WebLocalFrameImpl::setAutofillClient(WebAutofillClient* autofillClient)
 {
     m_autofillClient = autofillClient;
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
index ecc3356..c2618b72 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -235,7 +235,6 @@
     v8::Local<v8::Value> createTestInterface(const AtomicString& name);
 
     // WebLocalFrame methods:
-    void initializeToReplaceRemoteFrame(WebRemoteFrame*, const WebString& name, WebSandboxFlags, const WebFrameOwnerProperties&) override;
     void setAutofillClient(WebAutofillClient*) override;
     WebAutofillClient* autofillClient() override;
     void setDevToolsAgentClient(WebDevToolsAgentClient*) override;
@@ -267,6 +266,7 @@
     void willDetachParent();
 
     static WebLocalFrameImpl* create(WebTreeScopeType, WebFrameClient*);
+    static WebLocalFrameImpl* createProvisional(WebFrameClient*, WebRemoteFrame*, WebSandboxFlags, const WebFrameOwnerProperties&);
     ~WebLocalFrameImpl() override;
 
     PassRefPtrWillBeRawPtr<LocalFrame> createChildFrame(const FrameLoadRequest&, const AtomicString& name, HTMLFrameOwnerElement*);
@@ -355,6 +355,7 @@
     friend class FrameLoaderClientImpl;
 
     WebLocalFrameImpl(WebTreeScopeType, WebFrameClient*);
+    WebLocalFrameImpl(WebRemoteFrame*, WebFrameClient*);
 
     // Sets the local core frame and registers destruction observers.
     void setCoreFrame(PassRefPtrWillBeRawPtr<LocalFrame>);
diff --git a/third_party/WebKit/Source/web/tests/FrameTestHelpers.h b/third_party/WebKit/Source/web/tests/FrameTestHelpers.h
index dc110ad..74be950 100644
--- a/third_party/WebKit/Source/web/tests/FrameTestHelpers.h
+++ b/third_party/WebKit/Source/web/tests/FrameTestHelpers.h
@@ -163,7 +163,7 @@
         WebDOMMessageEvent) override { }
 
 private:
-    WebRemoteFrameImpl* const m_frame;
+    RawPtrWillBePersistent<WebRemoteFrameImpl> const m_frame;
 };
 
 class TestWebViewClient : public WebViewClient {
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index e31d13e..5bb8dd90 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -7015,8 +7015,7 @@
     mainFrame()->swap(remoteFrame);
 
     FrameTestHelpers::TestWebFrameClient client;
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &client);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&client, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     remoteFrame->swap(localFrame);
 
     // Finally, make sure an embedder triggered load in the local frame swapped
@@ -7091,8 +7090,7 @@
     swapAndVerifyFirstChildConsistency("local->remote", mainFrame(), remoteFrame);
 
     FrameTestHelpers::TestWebFrameClient client;
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &client);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&client, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     swapAndVerifyFirstChildConsistency("remote->local", mainFrame(), localFrame);
 
     // FIXME: This almost certainly fires more load events on the iframe element
@@ -7130,8 +7128,7 @@
     swapAndVerifyMiddleChildConsistency("local->remote", mainFrame(), remoteFrame);
 
     FrameTestHelpers::TestWebFrameClient client;
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &client);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&client, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     swapAndVerifyMiddleChildConsistency("remote->local", mainFrame(), localFrame);
 
     // FIXME: This almost certainly fires more load events on the iframe element
@@ -7166,8 +7163,7 @@
     swapAndVerifyLastChildConsistency("local->remote", mainFrame(), remoteFrame);
 
     FrameTestHelpers::TestWebFrameClient client;
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &client);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&client, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     swapAndVerifyLastChildConsistency("remote->local", mainFrame(), localFrame);
 
     // FIXME: This almost certainly fires more load events on the iframe element
@@ -7211,8 +7207,7 @@
     WebRemoteFrame* childRemoteFrame = remoteFrame->createRemoteChild(WebTreeScopeType::Document, "", WebSandboxFlags::None, &remoteFrameClient2);
 
     FrameTestHelpers::TestWebFrameClient client;
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &client);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&client, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     swapAndVerifySubframeConsistency("remote->local", targetFrame, localFrame);
 
     // FIXME: This almost certainly fires more load events on the iframe element
@@ -7255,8 +7250,7 @@
 
     // Now check that remote -> local works too, since it goes through a different code path.
     FrameTestHelpers::TestWebFrameClient client;
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &client);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&client, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     remoteFrame->swap(localFrame);
     v8::Local<v8::Value> localWindow = mainFrame()->executeScriptAndReturnValue(WebScriptSource(
         "document.querySelector('#frame2').contentWindow;"));
@@ -7289,8 +7283,7 @@
     EXPECT_TRUE(windowTop->StrictEquals(remoteWindowTop));
 
     FrameTestHelpers::TestWebFrameClient client;
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &client);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&client, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     remoteFrame->swap(localFrame);
     v8::Local<v8::Value> localWindowTop = mainFrame()->executeScriptAndReturnValue(WebScriptSource("saved.top"));
     EXPECT_TRUE(localWindowTop->IsObject());
@@ -7435,8 +7428,7 @@
     ASSERT_EQ(mainFrame()->firstChild(), remoteFrame);
 
     RemoteToLocalSwapWebFrameClient client(remoteFrame);
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &client);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&client, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");
     EXPECT_EQ(WebInitialCommitInChildFrame, client.historyCommitType());
 
@@ -7460,8 +7452,7 @@
     ASSERT_EQ(mainFrame()->firstChild(), remoteFrame);
 
     RemoteToLocalSwapWebFrameClient client(remoteFrame);
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &client);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&client, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     localFrame->setCommittedFirstRealLoad();
     FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");
     EXPECT_EQ(WebStandardCommit, client.historyCommitType());
@@ -7492,8 +7483,7 @@
 
     // Swap back to a LocalFrame.
     RemoteToLocalSwapWebFrameClient client(remoteFrame);
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &client);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "frame1", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&client, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");
     EXPECT_EQ(uniqueName.utf8(), localFrame->uniqueName().utf8());
     EXPECT_EQ(uniqueName.utf8(), WebString(toWebLocalFrameImpl(localFrame)->frame()->loader().currentItem()->target()).utf8());
@@ -7511,8 +7501,7 @@
     EXPECT_EQ(uniqueName2.utf8(), WebString(toWebRemoteFrameImpl(remoteFrame2)->frame()->tree().uniqueName()).utf8());
 
     RemoteToLocalSwapWebFrameClient client2(remoteFrame2);
-    WebLocalFrame* localFrame2 = WebLocalFrame::create(WebTreeScopeType::Document, &client2);
-    localFrame2->initializeToReplaceRemoteFrame(remoteFrame2, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame2 = WebLocalFrame::createProvisional(&client2, remoteFrame2, WebSandboxFlags::None, WebFrameOwnerProperties());
     FrameTestHelpers::loadFrame(localFrame2, m_baseURL + "subframe-hello.html");
     EXPECT_EQ(uniqueName2.utf8(), localFrame2->uniqueName().utf8());
     EXPECT_EQ(uniqueName2.utf8(), WebString(toWebLocalFrameImpl(localFrame2)->frame()->loader().currentItem()->target()).utf8());
@@ -7650,8 +7639,7 @@
 
     // Do a remote-to-local swap in the popup.
     FrameTestHelpers::TestWebFrameClient popupLocalClient;
-    WebLocalFrame* popupLocalFrame = WebLocalFrame::create(WebTreeScopeType::Document, &popupLocalClient);
-    popupLocalFrame->initializeToReplaceRemoteFrame(popupRemoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* popupLocalFrame = WebLocalFrame::createProvisional(&popupLocalClient, popupRemoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     popupRemoteFrame->swap(popupLocalFrame);
 
     // The initial document created during the remote-to-local swap should have
@@ -7673,8 +7661,7 @@
 
     // Now swap in a local frame. It shouldn't crash.
     FrameTestHelpers::TestWebFrameClient localClient;
-    WebLocalFrame* localFrame = WebLocalFrame::create(WebTreeScopeType::Document, &localClient);
-    localFrame->initializeToReplaceRemoteFrame(remoteFrame, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localFrame = WebLocalFrame::createProvisional(&localClient, remoteFrame, WebSandboxFlags::None, WebFrameOwnerProperties());
     remoteFrame->swap(localFrame);
 
     // And the opener cycle should still be preserved.
@@ -8021,8 +8008,7 @@
 
     // Do a remote-to-local swap of the top frame.
     FrameTestHelpers::TestWebFrameClient localClient;
-    WebLocalFrame* localRoot = WebLocalFrame::create(WebTreeScopeType::Document, &localClient);
-    localRoot->initializeToReplaceRemoteFrame(remoteRoot, "", WebSandboxFlags::None, WebFrameOwnerProperties());
+    WebLocalFrame* localRoot = WebLocalFrame::createProvisional(&localClient, remoteRoot, WebSandboxFlags::None, WebFrameOwnerProperties());
     remoteRoot->swap(localRoot);
 
     // Load a page with a child frame in the new root to make sure this doesn't
diff --git a/third_party/WebKit/Tools/Scripts/display-profiler-output b/third_party/WebKit/Tools/Scripts/display-profiler-output
deleted file mode 100755
index 0a8c15e9c..0000000
--- a/third_party/WebKit/Tools/Scripts/display-profiler-output
+++ /dev/null
@@ -1,938 +0,0 @@
-#!/usr/bin/env ruby
-
-# Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-#    notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
-# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-# THE POSSIBILITY OF SUCH DAMAGE.
-
-require 'rubygems'
-
-require 'readline'
-
-begin
-    require 'json'
-    require 'highline'
-rescue LoadError
-    $stderr.puts "Error: some required gems are not installed!"
-    $stderr.puts
-    $stderr.puts "Try running:"
-    $stderr.puts
-    $stderr.puts "sudo gem install json"
-    $stderr.puts "sudo gem install highline"
-    exit 1
-end
-
-class Bytecode
-    attr_accessor :bytecodes, :bytecodeIndex, :opcode, :description, :topCounts, :bottomCounts, :machineInlinees, :osrExits
-
-    def initialize(bytecodes, bytecodeIndex, opcode, description)
-        @bytecodes = bytecodes
-        @bytecodeIndex = bytecodeIndex
-        @opcode = opcode
-        @description = description
-        @topCounts = [] # "source" counts
-        @bottomCounts = {} # "machine" counts, maps compilations to counts
-        @machineInlinees = {} # maps my compilation to a set of inlinees
-        @osrExits = []
-    end
-
-    def shouldHaveCounts?
-        @opcode != "op_call_put_result"
-    end
-
-    def addTopCount(count)
-        @topCounts << count
-    end
-
-    def addBottomCountForCompilation(count, compilation)
-        @bottomCounts[compilation] = [] unless @bottomCounts[compilation]
-        @bottomCounts[compilation] << count
-    end
-
-    def addMachineInlinee(compilation, inlinee)
-        @machineInlinees[compilation] = {} unless @machineInlinees[compilation]
-        @machineInlinees[compilation][inlinee] = true
-    end
-
-    def totalTopExecutionCount
-        sum = 0
-        @topCounts.each {
-            | value |
-            sum += value.count
-        }
-        sum
-    end
-
-    def topExecutionCount(engine)
-        sum = 0
-        @topCounts.each {
-            | value |
-            if value.engine == engine
-                sum += value.count
-            end
-        }
-        sum
-    end
-
-    def totalBottomExecutionCount
-        sum = 0
-        @bottomCounts.each_value {
-            | counts |
-            max = 0
-            counts.each {
-                | value |
-                max = [max, value.count].max
-            }
-            sum += max
-        }
-        sum
-    end
-
-    def bottomExecutionCount(engine)
-        sum = 0
-        @bottomCounts.each_pair {
-            | compilation, counts |
-            if compilation.engine == engine
-                max = 0
-                counts.each {
-                    | value |
-                    max = [max, value.count].max
-                }
-                sum += max
-            end
-        }
-        sum
-    end
-
-    def totalExitCount
-        sum = 0
-        @osrExits.each {
-            | exit |
-            sum += exit.count
-        }
-        sum
-    end
-end
-
-class Bytecodes
-    attr_accessor :codeHash, :inferredName, :source, :instructionCount, :machineInlineSites, :compilations
-
-    def initialize(json)
-        @codeHash = json["hash"].to_s
-        @inferredName = json["inferredName"].to_s
-        @source = json["sourceCode"].to_s
-        @instructionCount = json["instructionCount"].to_i
-        @bytecode = {}
-        json["bytecode"].each {
-            | subJson |
-            index = subJson["bytecodeIndex"].to_i
-            @bytecode[index] = Bytecode.new(self, index, subJson["opcode"].to_s, subJson["description"].to_s)
-        }
-        @machineInlineSites = {} # maps compilation to a set of origins
-        @compilations = []
-    end
-
-    def name(limit)
-        if to_s.size > limit
-            "\##{@codeHash}"
-        else
-            to_s
-        end
-    end
-
-    def to_s
-        "#{@inferredName}\##{@codeHash}"
-    end
-
-    def matches(pattern)
-        if pattern =~ /^#/
-            $~.post_match == @codeHash
-        elsif pattern =~ /#/
-            pattern == to_s
-        else
-            pattern == @inferredName or pattern == @codeHash
-        end
-    end
-
-    def each
-        @bytecode.values.sort{|a, b| a.bytecodeIndex <=> b.bytecodeIndex}.each {
-            | value |
-            yield value
-        }
-    end
-
-    def bytecode(bytecodeIndex)
-        @bytecode[bytecodeIndex]
-    end
-
-    def addMachineInlineSite(compilation, origin)
-        @machineInlineSites[compilation] = {} unless @machineInlineSites[compilation]
-        @machineInlineSites[compilation][origin] = true
-    end
-
-    def totalMachineInlineSites
-        sum = 0
-        @machineInlineSites.each_value {
-            | set |
-            sum += set.size
-        }
-        sum
-    end
-
-    def sourceMachineInlineSites
-        set = {}
-        @machineInlineSites.each_value {
-            | mySet |
-            set.merge!(mySet)
-        }
-        set.size
-    end
-
-    def totalMaxTopExecutionCount
-        max = 0
-        @bytecode.each_value {
-            | bytecode |
-            max = [max, bytecode.totalTopExecutionCount].max
-        }
-        max
-    end
-
-    def maxTopExecutionCount(engine)
-        max = 0
-        @bytecode.each_value {
-            | bytecode |
-            max = [max, bytecode.topExecutionCount(engine)].max
-        }
-        max
-    end
-
-    def totalMaxBottomExecutionCount
-        max = 0
-        @bytecode.each_value {
-            | bytecode |
-            max = [max, bytecode.totalBottomExecutionCount].max
-        }
-        max
-    end
-
-    def maxBottomExecutionCount(engine)
-        max = 0
-        @bytecode.each_value {
-            | bytecode |
-            max = [max, bytecode.bottomExecutionCount(engine)].max
-        }
-        max
-    end
-
-    def totalExitCount
-        sum = 0
-        each {
-            | bytecode |
-            sum += bytecode.totalExitCount
-        }
-        sum
-    end
-end
-
-class ProfiledBytecode
-    attr_reader :bytecodeIndex, :description
-
-    def initialize(json)
-        @bytecodeIndex = json["bytecodeIndex"].to_i
-        @description = json["description"].to_s
-    end
-end
-
-class ProfiledBytecodes
-    attr_reader :header, :bytecodes
-
-    def initialize(json)
-        @header = json["header"]
-        @bytecodes = $bytecodes[json["bytecodesID"].to_i]
-        @sequence = json["bytecode"].map {
-            | subJson |
-            ProfiledBytecode.new(subJson)
-        }
-    end
-
-    def each
-        @sequence.each {
-            | description |
-            yield description
-        }
-    end
-end
-
-def originStackFromJSON(json)
-    json.map {
-        | subJson |
-        $bytecodes[subJson["bytecodesID"].to_i].bytecode(subJson["bytecodeIndex"].to_i)
-    }
-end
-
-class CompiledBytecode
-    attr_accessor :origin, :description
-
-    def initialize(json)
-        @origin = originStackFromJSON(json["origin"])
-        @description = json["description"].to_s
-    end
-end
-
-class ExecutionCounter
-    attr_accessor :origin, :engine, :count
-
-    def initialize(origin, engine, count)
-        @origin = origin
-        @engine = engine
-        @count = count
-    end
-end
-
-class OSRExit
-    attr_reader :compilation, :origin, :codeAddresses, :exitKind, :isWatchpoint, :count
-
-    def initialize(compilation, origin, codeAddresses, exitKind, isWatchpoint, count)
-        @compilation = compilation
-        @origin = origin
-        @codeAddresses = codeAddresses
-        @exitKind = exitKind
-        @isWatchpoint = isWatchpoint
-        @count = count
-    end
-
-    def dumpForDisplay(prefix)
-        puts(prefix + "EXIT: due to #{@exitKind}, #{@count} times")
-    end
-end
-
-class Compilation
-    attr_accessor :bytecode, :engine, :descriptions, :counters, :compilationIndex
-    attr_accessor :osrExits, :profiledBytecodes, :numInlinedGetByIds, :numInlinedPutByIds
-    attr_accessor :numInlinedCalls
-
-    def initialize(json)
-        @bytecode = $bytecodes[json["bytecodesID"].to_i]
-        @bytecode.compilations << self
-        @compilationIndex = @bytecode.compilations.size
-        @engine = json["compilationKind"]
-        @descriptions = json["descriptions"].map {
-            | subJson |
-            CompiledBytecode.new(subJson)
-        }
-        @descriptions.each {
-            | description |
-            next if description.origin.empty?
-            description.origin[1..-1].each_with_index {
-                | inlinee, index |
-                description.origin[0].addMachineInlinee(self, inlinee.bytecodes)
-                inlinee.bytecodes.addMachineInlineSite(self, description.origin[0...index])
-            }
-        }
-        @counters = {}
-        json["counters"].each {
-            | subJson |
-            origin = originStackFromJSON(subJson["origin"])
-            counter = ExecutionCounter.new(origin, @engine, subJson["executionCount"].to_i)
-            @counters[origin] = counter
-            origin[-1].addTopCount(counter)
-            origin[0].addBottomCountForCompilation(counter, self)
-        }
-        @osrExits = {}
-        json["osrExits"].each {
-            | subJson |
-            osrExit = OSRExit.new(self, originStackFromJSON(subJson["origin"]),
-                                  json["osrExitSites"][subJson["id"]].map {
-                                      | value |
-                                      value.hex
-                                  }, subJson["exitKind"], subJson["isWatchpoint"],
-                                  subJson["count"])
-            osrExit.codeAddresses.each {
-                | codeAddress |
-                osrExits[codeAddress] = [] unless osrExits[codeAddress]
-                osrExits[codeAddress] << osrExit
-            }
-            osrExit.origin[-1].osrExits << osrExit
-        }
-        @profiledBytecodes = []
-        json["profiledBytecodes"].each {
-            | subJson |
-            @profiledBytecodes << ProfiledBytecodes.new(subJson)
-        }
-        @numInlinedGetByIds = json["numInlinedGetByIds"]
-        @numInlinedPutByIds = json["numInlinedPutByIds"]
-        @numInlinedCalls = json["numInlinedCalls"]
-    end
-
-    def counter(origin)
-        @counters[origin]
-    end
-
-    def to_s
-        "#{bytecode}-#{compilationIndex}-#{engine}"
-    end
-end
-
-class DescriptionLine
-    attr_reader :actualCountsString, :sourceCountsString, :disassembly, :shouldShow
-
-    def initialize(actualCountsString, sourceCountsString, disassembly, shouldShow)
-        @actualCountsString = actualCountsString
-        @sourceCountsString = sourceCountsString
-        @disassembly = disassembly
-        @shouldShow = shouldShow
-    end
-
-    def codeAddress
-        if @disassembly =~ /^\s*(0x[0-9a-fA-F]+):/
-            $1.hex
-        else
-            nil
-        end
-    end
-end
-
-if ARGV.length != 1
-    $stderr.puts "Usage: display-profiler-output <path to profiler output file>"
-    $stderr.puts
-    $stderr.puts "The typical usage pattern for the profiler currently looks something like:"
-    $stderr.puts
-    $stderr.puts "Path/To/jsc -p profile.json myprogram.js"
-    $stderr.puts "display-profiler-output profile.json"
-    exit 1
-end
-
-$json = JSON::parse(IO::read(ARGV[0]))
-$bytecodes = $json["bytecodes"].map {
-    | subJson |
-    Bytecodes.new(subJson)
-}
-$compilations = $json["compilations"].map {
-    | subJson |
-    Compilation.new(subJson)
-}
-$engines = ["Baseline", "DFG"]
-
-def lpad(str,chars)
-  if str.length>chars
-    str
-  else
-    "%#{chars}s"%(str)
-  end
-end
-
-def rpad(str, chars)
-    while str.length < chars
-        str += " "
-    end
-    str
-end
-
-def center(str, chars)
-    while str.length < chars
-        str += " "
-        if str.length < chars
-            str = " " + str
-        end
-    end
-    str
-end
-
-def mayBeHash(hash)
-    hash =~ /#/ or hash.size == 6
-end
-
-def sourceOnOneLine(source, limit)
-    source.gsub(/\s+/, ' ')[0...limit]
-end
-
-def screenWidth
-    if $stdin.tty?
-        HighLine::SystemExtensions.terminal_size[0]
-    else
-        200
-    end
-end
-
-def summary(mode)
-    remaining = screenWidth
-
-    # Figure out how many columns we need for the code block names, and for counts
-    maxCount = 0
-    maxName = 0
-    $bytecodes.each {
-        | bytecodes |
-        maxCount = ([maxCount] + $engines.map {
-                        | engine |
-                        bytecodes.maxTopExecutionCount(engine)
-                    } + $engines.map {
-                        | engine |
-                        bytecodes.maxBottomExecutionCount(engine)
-                    }).max
-        maxName = [bytecodes.to_s.size, maxName].max
-    }
-    maxCountDigits = maxCount.to_s.size
-
-    hashCols = [[maxName, 30].min, "CodeBlock".size].max
-    remaining -= hashCols + 1
-
-    countCols = [maxCountDigits * $engines.size, "Source Counts".size].max
-    remaining -= countCols + 1
-
-    if mode == :full
-        instructionCountCols = 6
-        remaining -= instructionCountCols + 1
-
-        machineCountCols = [maxCountDigits * $engines.size, "Machine Counts".size].max
-        remaining -= machineCountCols + 1
-
-        compilationsCols = 7
-        remaining -= compilationsCols + 1
-
-        inlinesCols = 9
-        remaining -= inlinesCols + 1
-
-        exitCountCols = 7
-        remaining -= exitCountCols + 1
-
-        recentOptsCols = 12
-        remaining -= recentOptsCols + 1
-    end
-
-    if remaining > 0
-        sourceCols = remaining
-    else
-        sourceCols = nil
-    end
-
-    print(center("CodeBlock", hashCols))
-    if mode == :full
-        print(" " + center("#Instr", instructionCountCols))
-    end
-    print(" " + center("Source Counts", countCols))
-    if mode == :full
-        print(" " + center("Machine Counts", machineCountCols))
-        print(" " + center("#Compil", compilationsCols))
-        print(" " + center("Inlines", inlinesCols))
-        print(" " + center("#Exits", exitCountCols))
-        print(" " + center("Last Opts", recentOptsCols))
-    end
-    if sourceCols
-        print(" " + center("Source", sourceCols))
-    end
-    puts
-
-    print(center("", hashCols))
-    if mode == :full
-        print(" " + (" " * instructionCountCols))
-    end
-    print(" " + center("Base/DFG", countCols))
-    if mode == :full
-        print(" " + center("Base/DFG", machineCountCols))
-        print(" " + (" " * compilationsCols))
-        print(" " + center("Src/Total", inlinesCols))
-        print(" " + (" " * exitCountCols))
-        print(" " + center("Get/Put/Call", recentOptsCols))
-    end
-    puts
-    $bytecodes.sort {
-        | a, b |
-        b.totalMaxTopExecutionCount <=> a.totalMaxTopExecutionCount
-    }.each {
-        | bytecode |
-        print(center(bytecode.name(hashCols), hashCols))
-        if mode == :full
-            print(" " + center(bytecode.instructionCount.to_s, instructionCountCols))
-        end
-        print(" " +
-              center($engines.map {
-                         | engine |
-                         bytecode.maxTopExecutionCount(engine).to_s
-                     }.join("/"), countCols))
-        if mode == :full
-            print(" " + center($engines.map {
-                                   | engine |
-                                   bytecode.maxBottomExecutionCount(engine).to_s
-                               }.join("/"), machineCountCols))
-            print(" " + center(bytecode.compilations.size.to_s, compilationsCols))
-            print(" " + center(bytecode.sourceMachineInlineSites.to_s + "/" + bytecode.totalMachineInlineSites.to_s, inlinesCols))
-            print(" " + center(bytecode.totalExitCount.to_s, exitCountCols))
-            lastCompilation = bytecode.compilations[-1]
-            if lastCompilation
-                optData = [lastCompilation.numInlinedGetByIds,
-                           lastCompilation.numInlinedPutByIds,
-                           lastCompilation.numInlinedCalls]
-            else
-                optData = ["N/A"]
-            end
-            print(" " + center(optData.join('/'), recentOptsCols))
-        end
-        if sourceCols
-            print(" " + sourceOnOneLine(bytecode.source, sourceCols))
-        end
-        puts
-    }
-end
-
-def executeCommand(*commandArray)
-    command = commandArray[0]
-    args = commandArray[1..-1]
-    case command
-    when "help", "h", "?"
-        puts "summary (s)     Print a summary of code block execution rates."
-        puts "full (f)        Same as summary, but prints more information."
-        puts "source          Show the source for a code block."
-        puts "bytecode (b)    Show the bytecode for a code block, with counts."
-        puts "profiling (p)   Show the (internal) profiling data for a code block."
-        puts "display (d)     Display details for a code block."
-        puts "inlines         Show all inlining stacks that the code block was on."
-        puts "help (h)        Print this message."
-        puts "quit (q)        Quit."
-    when "quit", "q", "exit"
-        exit 0
-    when "summary", "s"
-        summary(:summary)
-    when "full", "f"
-        summary(:full)
-    when "source"
-        if args.length != 1
-            puts "Usage: source <code block hash>"
-            return
-        end
-        $bytecodes.each {
-            | bytecode |
-            if bytecode.matches(args[0])
-                puts bytecode.source
-            end
-        }
-    when "bytecode", "b"
-        if args.length != 1
-            puts "Usage: source <code block hash>"
-            return
-        end
-
-        hash = args[0]
-
-        countCols = 10 * $engines.size
-        machineCols = 10 * $engines.size
-        pad = 1
-        while (countCols + 1 + machineCols + pad) % 8 != 0
-            pad += 1
-        end
-
-        $bytecodes.each {
-            | bytecodes |
-            next unless bytecodes.matches(hash)
-            puts(center("Source Counts", countCols) + " " + center("Machine Counts", machineCols) +
-                 (" " * pad) + center("Bytecode for #{bytecodes}", screenWidth - pad - countCols - 1 - machineCols))
-            puts(center("Base/DFG", countCols) + " " + center("Base/DFG", countCols))
-            bytecodes.each {
-                | bytecode |
-                if bytecode.shouldHaveCounts?
-                    countsString = $engines.map {
-                        | myEngine |
-                        bytecode.topExecutionCount(myEngine)
-                    }.join("/")
-                    machineString = $engines.map {
-                        | myEngine |
-                        bytecode.bottomExecutionCount(myEngine)
-                    }.join("/")
-                else
-                    countsString = ""
-                    machineString = ""
-                end
-                puts(center(countsString, countCols) + " " + center(machineString, machineCols) + (" " * pad) + bytecode.description.chomp)
-                bytecode.osrExits.each {
-                    | exit |
-                    puts(center("!!!!!", countCols) + " " + center("!!!!!", machineCols) + (" " * (pad + 10)) +
-                         "EXIT: in #{exit.compilation} due to #{exit.exitKind}, #{exit.count} times")
-                }
-            }
-        }
-    when "profiling", "p"
-        if args.length != 1
-            puts "Usage: profiling <code block hash>"
-            return
-        end
-
-        hash = args[0]
-
-        first = true
-        $compilations.each {
-            | compilation |
-
-            compilation.profiledBytecodes.each {
-                | profiledBytecodes |
-                if profiledBytecodes.bytecodes.matches(hash)
-                    if first
-                        first = false
-                    else
-                        puts
-                    end
-
-                    puts "Compilation #{compilation}:"
-                    profiledBytecodes.header.each {
-                        | header |
-                        puts(" " * 6 + header)
-                    }
-                    profiledBytecodes.each {
-                        | bytecode |
-                        puts(" " * 8 + bytecode.description)
-                        profiledBytecodes.bytecodes.bytecode(bytecode.bytecodeIndex).osrExits.each {
-                            | exit |
-                            if exit.compilation == compilation
-                                puts(" !!!!!           EXIT: due to #{exit.exitKind}, #{exit.count} times")
-                            end
-                        }
-                    }
-                end
-            }
-        }
-    when "inlines"
-        if args.length != 1
-            puts "Usage: inlines <code block hash>"
-            return
-        end
-
-        hash = args[0]
-
-        $bytecodes.each {
-            | bytecodes |
-            next unless bytecodes.matches(hash)
-
-            # FIXME: print something useful to say more about which code block this is.
-
-            $compilations.each {
-                | compilation |
-                myOrigins = []
-                compilation.descriptions.each {
-                    | description |
-                    if description.origin.index {
-                            | myBytecode |
-                            bytecodes == myBytecode.bytecodes
-                        }
-                        myOrigins << description.origin
-                    end
-                }
-                myOrigins.uniq!
-                myOrigins.sort! {
-                    | a, b |
-                    result = 0
-                    [a.size, b.size].min.times {
-                        | index |
-                        result = a[index].bytecodeIndex <=> b[index].bytecodeIndex
-                        break if result != 0
-                    }
-                    result
-                }
-
-                next if myOrigins.empty?
-
-                printArray = []
-                lastPrintStack = []
-
-                def originToPrintStack(origin)
-                    (0...(origin.size - 1)).map {
-                        | index |
-                        "bc\##{origin[index].bytecodeIndex} --> #{origin[index + 1].bytecodes}"
-                    }
-                end
-
-                def printStack(printArray, stack, lastStack)
-                    stillCommon = true
-                    stack.each_with_index {
-                        | entry, index |
-                        next if stillCommon and entry == lastStack[index]
-                        printArray << ("    " * (index + 1) + entry)
-                        stillCommon = false
-                    }
-                end
-
-                myOrigins.each {
-                    | origin |
-                    currentPrintStack = originToPrintStack(origin)
-                    printStack(printArray, currentPrintStack, lastPrintStack)
-                    lastPrintStack = currentPrintStack
-                }
-
-                next if printArray.empty?
-
-                puts "Compilation #{compilation}:"
-                printArray.each {
-                    | entry |
-                    puts entry
-                }
-            }
-        }
-    when "display", "d"
-        compilationIndex = nil
-
-        case args.length
-        when 1
-            if args[0] == "*"
-                hash = nil
-            else
-                hash = args[0]
-            end
-            engine = nil
-        when 2
-            if mayBeHash(args[0])
-                hash = args[0]
-                engine = args[1]
-            else
-                engine = args[0]
-                hash = args[1]
-            end
-        else
-            puts "Usage: summary <code block hash> <engine>"
-            return
-        end
-
-        if hash and hash =~ /-([0-9]+)-/
-            hash = $~.pre_match
-            engine = $~.post_match
-            compilationIndex = $1.to_i
-        end
-
-        if engine and not $engines.index(engine)
-            pattern = Regexp.new(Regexp.escape(engine), "i")
-            trueEngine = nil
-            $engines.each {
-                | myEngine |
-                if myEngine =~ pattern
-                    trueEngine = myEngine
-                    break
-                end
-            }
-            unless trueEngine
-                puts "#{engine} is not a valid engine, try #{$engines.join(' or ')}."
-                return
-            end
-            engine = trueEngine
-        end
-
-        actualCountCols = 13
-        sourceCountCols = 10 * $engines.size
-
-        first = true
-        $compilations.each {
-            | compilation |
-            next if hash and not compilation.bytecode.matches(hash)
-            next if engine and compilation.engine != engine
-            next if compilationIndex and compilation.compilationIndex != compilationIndex
-
-            if first
-                first = false
-            else
-                puts
-            end
-
-            puts("Compilation #{compilation}:")
-            puts("    Num inlined: GetByIds: #{compilation.numInlinedGetByIds}  PutByIds: #{compilation.numInlinedPutByIds}  Calls: #{compilation.numInlinedCalls}")
-            puts(center("Actual Counts", actualCountCols) + " " + center("Source Counts", sourceCountCols) + " " + center("Disassembly in #{compilation.engine}", screenWidth - 1 - sourceCountCols - 1 - actualCountCols))
-            puts((" " * actualCountCols) + " " + center("Base/DFG", sourceCountCols))
-
-            lines = []
-
-            compilation.descriptions.each {
-                | description |
-                # FIXME: We should have a better way of detecting things like CountExecution nodes
-                # and slow path entries in the baseline JIT.
-                if description.description =~ /CountExecution\(/ and compilation.engine == "DFG"
-                    shouldShow = false
-                else
-                    shouldShow = true
-                end
-                if description.origin.empty? or not description.origin[-1].shouldHaveCounts? or (compilation.engine == "Baseline" and description.description =~ /^\s*\(S\)/)
-                    actualCountsString = ""
-                    sourceCountsString = ""
-                else
-                    actualCountsString = compilation.counter(description.origin).count.to_s
-                    sourceCountsString = $engines.map {
-                        | myEngine |
-                        description.origin[-1].topExecutionCount(myEngine)
-                    }.join("/")
-                end
-                description.description.split("\n").each {
-                    | line |
-                    lines << DescriptionLine.new(actualCountsString, sourceCountsString, line.chomp, shouldShow)
-                }
-            }
-
-            exitPrefix = center("!!!!!", actualCountCols) + " " + center("!!!!!", sourceCountCols) + (" " * 25)
-
-            lines.each_with_index {
-                | line, index |
-                codeAddress = line.codeAddress
-                if codeAddress
-                    list = compilation.osrExits[codeAddress]
-                    if list
-                        list.each {
-                            | exit |
-                            if exit.isWatchpoint
-                                exit.dumpForDisplay(exitPrefix)
-                            end
-                        }
-                    end
-                end
-                if line.shouldShow
-                    puts(center(line.actualCountsString, actualCountCols) + " " + center(line.sourceCountsString, sourceCountCols) + " " + line.disassembly)
-                end
-                if codeAddress
-                    # Find the next disassembly address.
-                    endIndex = index + 1
-                    endAddress = nil
-                    while endIndex < lines.size
-                        myAddress = lines[endIndex].codeAddress
-                        if myAddress
-                            endAddress = myAddress
-                            break
-                        end
-                        endIndex += 1
-                    end
-
-                    if endAddress
-                        list = compilation.osrExits[endAddress]
-                        if list
-                            list.each {
-                                | exit |
-                                unless exit.isWatchpoint
-                                    exit.dumpForDisplay(exitPrefix)
-                                end
-                            }
-                        end
-                    end
-                end
-            }
-        }
-    else
-        puts "Invalid command: #{command}"
-    end
-end
-
-if $stdin.tty?
-    executeCommand("full")
-end
-
-while commandLine = Readline.readline("> ", true)
-    executeCommand(*commandLine.split)
-end
-
diff --git a/third_party/WebKit/Tools/Scripts/find-included-framework-headers b/third_party/WebKit/Tools/Scripts/find-included-framework-headers
deleted file mode 100755
index 759a60b5..0000000
--- a/third_party/WebKit/Tools/Scripts/find-included-framework-headers
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1.  Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-# 2.  Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# A script to find headers included from the given frameworks by files in the
-# current directory (and subdirectories).
-
-for framework in $*; do
-    echo -e "\n$framework\n=================="
-    find . \( -name '*.cpp' -o -name '*.h' -o -name '*.m' -o -name '*.mm' \) -exec grep "<$framework/" {} ';' | sed -e 's|.*/\(.*\.h\).*|\1|' | sort -u
-done
diff --git a/third_party/WebKit/Tools/Scripts/test-webkitpy b/third_party/WebKit/Tools/Scripts/test-webkitpy
index d7b5d996..4e2c7bd 100755
--- a/third_party/WebKit/Tools/Scripts/test-webkitpy
+++ b/third_party/WebKit/Tools/Scripts/test-webkitpy
@@ -41,6 +41,7 @@
 
 import typ
 
+skip = []
 if sys.platform == 'win32':
     # These test fail on win32. We could annotate some of these in
     # class-level skips, but we don't support package/module-level skips.
@@ -52,12 +53,6 @@
         'webkitpy.w3c.*',
         'webkitpy.layout_tests.layout_package.bot_test_expectations_unittest.*',
     ]
-else:
-    # The scm tests are really slow, so we skip them by default.
-    # bugs.webkit.org/show_bug.cgi?id=31818 .
-    skip = [
-        'webkitpy.common.checkout.scm.scm_unittest.*',
-    ]
 
 sys.exit(typ.main(top_level_dir=scripts_dir,
                   skip=skip,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
index 9314eb5..0cdf0ce 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
@@ -32,6 +32,7 @@
 import os
 import re
 
+import webkitpy.common.config
 from webkitpy.common.checkout.scm.scm import SCM
 from webkitpy.common.memoized import memoized
 from webkitpy.common.system.executive import Executive, ScriptError
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py
index 48635da..9c609e0 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-"""Pull latest revisions of the W3C test repos and update our DEPS entries."""
+"""Pull latest revisions of a W3C test repo and make a local commit."""
 
 import argparse
 import re
@@ -30,17 +30,21 @@
         self.print_('## noting the current Blink commitish')
         blink_commitish = self.run(['git', 'show-ref', 'HEAD'])[1].split()[0]
 
-        wpt_import_text = self.update('web-platform-tests',
-                                      'https://chromium.googlesource.com/external/w3c/web-platform-tests.git')
+        wpt_import_text = ''
+        if self.target == 'wpt':
+            wpt_import_text = self.update('web-platform-tests',
+                                          'https://chromium.googlesource.com/external/w3c/web-platform-tests.git')
 
-        for resource in ['testharnessreport.js', 'vendor-prefix.js']:
-            source = self.path_from_webkit_base('LayoutTests', 'resources', resource)
-            destination = self.path_from_webkit_base('LayoutTests', 'imported', 'web-platform-tests', 'resources', resource)
-            self.copyfile(source, destination)
-            self.run(['git', 'add', destination])
+            for resource in ['testharnessreport.js', 'vendor-prefix.js']:
+                source = self.path_from_webkit_base('LayoutTests', 'resources', resource)
+                destination = self.path_from_webkit_base('LayoutTests', 'imported', 'web-platform-tests', 'resources', resource)
+                self.copyfile(source, destination)
+                self.run(['git', 'add', destination])
 
-        css_import_text = self.update('csswg-test',
-                                      'https://chromium.googlesource.com/external/w3c/csswg-test.git')
+        css_import_text = ''
+        if self.target == 'css':
+            css_import_text = self.update('csswg-test',
+                                          'https://chromium.googlesource.com/external/w3c/csswg-test.git')
 
         self.commit_changes_if_needed(blink_commitish, css_import_text, wpt_import_text)
 
@@ -55,11 +59,14 @@
                             help='allow script to run even if we have local blink commits')
         parser.add_argument('--keep-w3c-repos-around', action='store_true',
                             help='leave the w3c repos around that were imported previously.')
+        parser.add_argument('target', choices=['css', 'wpt'],
+                            help='Target repository.  "css" for csswg-test, "wpt" for web-platform-tests.')
 
         args = parser.parse_args(argv)
         self.allow_local_blink_commits = args.allow_local_blink_commits
         self.keep_w3c_repos_around = args.keep_w3c_repos_around
         self.verbose = args.verbose
+        self.target = args.target
 
     def checkout_is_okay(self):
         if self.run(['git', 'diff', '--quiet', 'HEAD'], exit_on_failure=False)[0]:
diff --git a/third_party/WebKit/public/web/WebLocalFrame.h b/third_party/WebKit/public/web/WebLocalFrame.h
index c412834..d561de9 100644
--- a/third_party/WebKit/public/web/WebLocalFrame.h
+++ b/third_party/WebKit/public/web/WebLocalFrame.h
@@ -33,6 +33,13 @@
     // It is valid to pass a null client pointer.
     BLINK_EXPORT static WebLocalFrame* create(WebTreeScopeType, WebFrameClient*);
 
+    // Used to create a provisional local frame in prepration for replacing a
+    // remote frame if the load commits. The returned frame is only partially
+    // attached to the frame tree: it has the same parent as its potential
+    // replacee but is invisible to the rest of the frames in the frame tree.
+    // If the load commits, call swap() to fully attach this frame.
+    BLINK_EXPORT static WebLocalFrame* createProvisional(WebFrameClient*, WebRemoteFrame*, WebSandboxFlags, const WebFrameOwnerProperties&);
+
     // Returns the WebFrame associated with the current V8 context. This
     // function can return 0 if the context is associated with a Document that
     // is not currently being displayed in a Frame.
@@ -49,11 +56,6 @@
 
     // Initialization ---------------------------------------------------------
 
-    // Used when we might swap from a remote frame to a local frame.
-    // Creates a provisional, semi-attached frame that will be fully
-    // swapped into the frame tree if it commits.
-    virtual void initializeToReplaceRemoteFrame(WebRemoteFrame*, const WebString& name, WebSandboxFlags, const WebFrameOwnerProperties&) = 0;
-
     virtual void setAutofillClient(WebAutofillClient*) = 0;
     virtual WebAutofillClient* autofillClient() = 0;
     virtual void setDevToolsAgentClient(WebDevToolsAgentClient*) = 0;
diff --git a/third_party/accessibility-audit/OWNERS b/third_party/accessibility-audit/OWNERS
deleted file mode 100644
index cd795ab..0000000
--- a/third_party/accessibility-audit/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-aboxhall@chromium.org
\ No newline at end of file
diff --git a/third_party/accessibility-audit/README.chromium b/third_party/accessibility-audit/README.chromium
index 6cf4986..8df33898 100644
--- a/third_party/accessibility-audit/README.chromium
+++ b/third_party/accessibility-audit/README.chromium
@@ -2,7 +2,7 @@
 Short Name: accessibility-audit
 URL: https://raw.githubusercontent.com/GoogleChrome/accessibility-developer-tools/master/dist/js/axs_testing.js
 Version: 0
-Revision: 404ede0f2186682fbbef624141e76ec2b601317d
+Revision: 3d4893b4ecd0eb8f4765e04479213d04b240f3e0
 License: Apache 2.0
 License File: LICENSE
 Security Critical: no
diff --git a/third_party/accessibility-audit/axs_testing.js b/third_party/accessibility-audit/axs_testing.js
index f075a05..f0e6f4a3 100644
--- a/third_party/accessibility-audit/axs_testing.js
+++ b/third_party/accessibility-audit/axs_testing.js
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Google Inc.
+ * Copyright 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,15 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * Generated from http://github.com/GoogleChrome/accessibility-developer-tools/tree/404ede0f2186682fbbef624141e76ec2b601317d
+ * Generated from http://github.com/GoogleChrome/accessibility-developer-tools/tree/3d4893b4ecd0eb8f4765e04479213d04b240f3e0
  *
  * See project README for build steps.
  */
-
+ 
 // AUTO-GENERATED CONTENT BELOW: DO NOT EDIT! See above for details.
 
-var fn = (function() {
-  var COMPILED = !0, goog = goog || {};
+var COMPILED = !0, goog = goog || {};
 goog.global = this;
 goog.isDef = function(a) {
   return void 0 !== a;
@@ -63,7 +62,7 @@
 goog.forwardDeclare = function(a) {
 };
 COMPILED || (goog.isProvided_ = function(a) {
-  return !goog.implicitNamespaces_[a] && goog.isDefAndNotNull(goog.getObjectByName(a));
+  return!goog.implicitNamespaces_[a] && goog.isDefAndNotNull(goog.getObjectByName(a));
 }, goog.implicitNamespaces_ = {});
 goog.getObjectByName = function(a, b) {
   for (var c = a.split("."), d = b || goog.global, e;e = c.shift();) {
@@ -154,14 +153,14 @@
     var b = goog.global.document;
     if ("complete" == b.readyState) {
       if (/\bdeps.js$/.test(a)) {
-        return !1;
+        return!1;
       }
       throw Error('Cannot write "' + a + '" after document load');
     }
     b.write('<script type="text/javascript" src="' + a + '">\x3c/script>');
-    return !0;
+    return!0;
   }
-  return !1;
+  return!1;
 }, goog.writeScripts_ = function() {
   function a(e) {
     if (!(e in d.written)) {
@@ -259,7 +258,7 @@
   return a[goog.UID_PROPERTY_] || (a[goog.UID_PROPERTY_] = ++goog.uidCounter_);
 };
 goog.hasUid = function(a) {
-  return !!a[goog.UID_PROPERTY_];
+  return!!a[goog.UID_PROPERTY_];
 };
 goog.removeUid = function(a) {
   "removeAttribute" in a && a.removeAttribute(goog.UID_PROPERTY_);
@@ -323,7 +322,7 @@
   }
 };
 goog.now = goog.TRUSTED_SITE && Date.now || function() {
-  return +new Date;
+  return+new Date;
 };
 goog.globalEval = function(a) {
   if (goog.global.execScript) {
@@ -422,24 +421,24 @@
 var axs = {};
 axs.browserUtils = {};
 axs.browserUtils.matchSelector = function(a, b) {
-  return a.matches ? a.matches(b) : a.webkitMatchesSelector ? a.webkitMatchesSelector(b) : a.mozMatchesSelector ? a.mozMatchesSelector(b) : a.msMatchesSelector ? a.msMatchesSelector(b) : !1;
+  return a.webkitMatchesSelector ? a.webkitMatchesSelector(b) : a.mozMatchesSelector ? a.mozMatchesSelector(b) : !1;
 };
 axs.constants = {};
 axs.constants.ARIA_ROLES = {alert:{namefrom:["author"], parent:["region"]}, alertdialog:{namefrom:["author"], namerequired:!0, parent:["alert", "dialog"]}, application:{namefrom:["author"], namerequired:!0, parent:["landmark"]}, article:{namefrom:["author"], parent:["document", "region"]}, banner:{namefrom:["author"], parent:["landmark"]}, button:{childpresentational:!0, namefrom:["contents", "author"], namerequired:!0, parent:["command"], properties:["aria-expanded", "aria-pressed"]}, checkbox:{namefrom:["contents", 
-"author"], namerequired:!0, parent:["input"], requiredProperties:["aria-checked"], properties:["aria-checked"]}, columnheader:{namefrom:["contents", "author"], namerequired:!0, parent:["gridcell", "sectionhead", "widget"], properties:["aria-sort"], scope:["row"]}, combobox:{mustcontain:["listbox", "textbox"], namefrom:["author"], namerequired:!0, parent:["select"], requiredProperties:["aria-expanded"], properties:["aria-expanded", "aria-autocomplete", "aria-required"]}, command:{"abstract":!0, namefrom:["author"], 
+"author"], namerequired:!0, parent:["input"], requiredProperties:["aria-checked"], properties:["aria-checked"]}, columnheader:{namefrom:["contents", "author"], namerequired:!0, parent:["gridcell", "sectionhead", "widget"], properties:["aria-sort"]}, combobox:{mustcontain:["listbox", "textbox"], namefrom:["author"], namerequired:!0, parent:["select"], requiredProperties:["aria-expanded"], properties:["aria-expanded", "aria-autocomplete", "aria-required"]}, command:{"abstract":!0, namefrom:["author"], 
 parent:["widget"]}, complementary:{namefrom:["author"], parent:["landmark"]}, composite:{"abstract":!0, childpresentational:!1, namefrom:["author"], parent:["widget"], properties:["aria-activedescendant"]}, contentinfo:{namefrom:["author"], parent:["landmark"]}, definition:{namefrom:["author"], parent:["section"]}, dialog:{namefrom:["author"], namerequired:!0, parent:["window"]}, directory:{namefrom:["contents", "author"], parent:["list"]}, document:{namefrom:[" author"], namerequired:!0, parent:["structure"], 
-properties:["aria-expanded"]}, form:{namefrom:["author"], parent:["landmark"]}, grid:{mustcontain:["row", "rowgroup"], namefrom:["author"], namerequired:!0, parent:["composite", "region"], properties:["aria-level", "aria-multiselectable", "aria-readonly"]}, gridcell:{namefrom:["contents", "author"], namerequired:!0, parent:["section", "widget"], properties:["aria-readonly", "aria-required", "aria-selected"], scope:["row"]}, group:{namefrom:[" author"], parent:["section"], properties:["aria-activedescendant"]}, 
+properties:["aria-expanded"]}, form:{namefrom:["author"], parent:["landmark"]}, grid:{mustcontain:["row", "rowgroup"], namefrom:["author"], namerequired:!0, parent:["composite", "region"], properties:["aria-level", "aria-multiselectable", "aria-readonly"]}, gridcell:{namefrom:["contents", "author"], namerequired:!0, parent:["section", "widget"], properties:["aria-readonly", "aria-required", "aria-selected"]}, group:{namefrom:[" author"], parent:["section"], properties:["aria-activedescendant"]}, 
 heading:{namerequired:!0, parent:["sectionhead"], properties:["aria-level"]}, img:{childpresentational:!0, namefrom:["author"], namerequired:!0, parent:["section"]}, input:{"abstract":!0, namefrom:["author"], parent:["widget"]}, landmark:{"abstract":!0, namefrom:["contents", "author"], namerequired:!1, parent:["region"]}, link:{namefrom:["contents", "author"], namerequired:!0, parent:["command"], properties:["aria-expanded"]}, list:{mustcontain:["group", "listitem"], namefrom:["author"], parent:["region"]}, 
-listbox:{mustcontain:["option"], namefrom:["author"], namerequired:!0, parent:["list", "select"], properties:["aria-multiselectable", "aria-required"]}, listitem:{namefrom:["contents", "author"], namerequired:!0, parent:["section"], properties:["aria-level", "aria-posinset", "aria-setsize"], scope:["list"]}, log:{namefrom:[" author"], namerequired:!0, parent:["region"]}, main:{namefrom:["author"], parent:["landmark"]}, marquee:{namerequired:!0, parent:["section"]}, math:{childpresentational:!0, namefrom:["author"], 
-parent:["section"]}, menu:{mustcontain:["group", "menuitemradio", "menuitem", "menuitemcheckbox"], namefrom:["author"], namerequired:!0, parent:["list", "select"]}, menubar:{namefrom:["author"], parent:["menu"]}, menuitem:{namefrom:["contents", "author"], namerequired:!0, parent:["command"], scope:["menu", "menubar"]}, menuitemcheckbox:{namefrom:["contents", "author"], namerequired:!0, parent:["checkbox", "menuitem"], scope:["menu", "menubar"]}, menuitemradio:{namefrom:["contents", "author"], namerequired:!0, 
-parent:["menuitemcheckbox", "radio"], scope:["menu", "menubar"]}, navigation:{namefrom:["author"], parent:["landmark"]}, note:{namefrom:["author"], parent:["section"]}, option:{namefrom:["contents", "author"], namerequired:!0, parent:["input"], properties:["aria-checked", "aria-posinset", "aria-selected", "aria-setsize"]}, presentation:{parent:["structure"]}, progressbar:{childpresentational:!0, namefrom:["author"], namerequired:!0, parent:["range"]}, radio:{namefrom:["contents", "author"], namerequired:!0, 
-parent:["checkbox", "option"]}, radiogroup:{mustcontain:["radio"], namefrom:["author"], namerequired:!0, parent:["select"], properties:["aria-required"]}, range:{"abstract":!0, namefrom:["author"], parent:["widget"], properties:["aria-valuemax", "aria-valuemin", "aria-valuenow", "aria-valuetext"]}, region:{namefrom:[" author"], parent:["section"]}, roletype:{"abstract":!0, properties:"aria-atomic aria-busy aria-controls aria-describedby aria-disabled aria-dropeffect aria-flowto aria-grabbed aria-haspopup aria-hidden aria-invalid aria-label aria-labelledby aria-live aria-owns aria-relevant".split(" ")}, 
-row:{mustcontain:["columnheader", "gridcell", "rowheader"], namefrom:["contents", "author"], parent:["group", "widget"], properties:["aria-level", "aria-selected"], scope:["grid", "rowgroup", "treegrid"]}, rowgroup:{mustcontain:["row"], namefrom:["contents", "author"], parent:["group"], scope:["grid"]}, rowheader:{namefrom:["contents", "author"], namerequired:!0, parent:["gridcell", "sectionhead", "widget"], properties:["aria-sort"], scope:["row"]}, search:{namefrom:["author"], parent:["landmark"]}, 
-section:{"abstract":!0, namefrom:["contents", "author"], parent:["structure"], properties:["aria-expanded"]}, sectionhead:{"abstract":!0, namefrom:["contents", "author"], parent:["structure"], properties:["aria-expanded"]}, select:{"abstract":!0, namefrom:["author"], parent:["composite", "group", "input"]}, separator:{childpresentational:!0, namefrom:["author"], parent:["structure"], properties:["aria-expanded", "aria-orientation"]}, scrollbar:{childpresentational:!0, namefrom:["author"], namerequired:!1, 
-parent:["input", "range"], requiredProperties:["aria-controls", "aria-orientation", "aria-valuemax", "aria-valuemin", "aria-valuenow"], properties:["aria-controls", "aria-orientation", "aria-valuemax", "aria-valuemin", "aria-valuenow"]}, slider:{childpresentational:!0, namefrom:["author"], namerequired:!0, parent:["input", "range"], requiredProperties:["aria-valuemax", "aria-valuemin", "aria-valuenow"], properties:["aria-valuemax", "aria-valuemin", "aria-valuenow", "aria-orientation"]}, spinbutton:{namefrom:["author"], 
-namerequired:!0, parent:["input", "range"], requiredProperties:["aria-valuemax", "aria-valuemin", "aria-valuenow"], properties:["aria-valuemax", "aria-valuemin", "aria-valuenow", "aria-required"]}, status:{parent:["region"]}, structure:{"abstract":!0, parent:["roletype"]}, tab:{namefrom:["contents", "author"], parent:["sectionhead", "widget"], properties:["aria-selected"], scope:["tablist"]}, tablist:{mustcontain:["tab"], namefrom:["author"], parent:["composite", "directory"], properties:["aria-level"]}, 
-tabpanel:{namefrom:["author"], namerequired:!0, parent:["region"]}, textbox:{namefrom:["author"], namerequired:!0, parent:["input"], properties:["aria-activedescendant", "aria-autocomplete", "aria-multiline", "aria-readonly", "aria-required"]}, timer:{namefrom:["author"], namerequired:!0, parent:["status"]}, toolbar:{namefrom:["author"], parent:["group"]}, tooltip:{namerequired:!0, parent:["section"]}, tree:{mustcontain:["group", "treeitem"], namefrom:["author"], namerequired:!0, parent:["select"], 
-properties:["aria-multiselectable", "aria-required"]}, treegrid:{mustcontain:["row"], namefrom:["author"], namerequired:!0, parent:["grid", "tree"]}, treeitem:{namefrom:["contents", "author"], namerequired:!0, parent:["listitem", "option"], scope:["group", "tree"]}, widget:{"abstract":!0, parent:["roletype"]}, window:{"abstract":!0, namefrom:[" author"], parent:["roletype"], properties:["aria-expanded"]}};
+listbox:{mustcontain:["option"], namefrom:["author"], namerequired:!0, parent:["list", "select"], properties:["aria-multiselectable", "aria-required"]}, listitem:{namefrom:["contents", "author"], namerequired:!0, parent:["section"], properties:["aria-level", "aria-posinset", "aria-setsize"]}, log:{namefrom:[" author"], namerequired:!0, parent:["region"]}, main:{namefrom:["author"], parent:["landmark"]}, marquee:{namerequired:!0, parent:["section"]}, math:{childpresentational:!0, namefrom:["author"], 
+parent:["section"]}, menu:{mustcontain:["group", "menuitemradio", "menuitem", "menuitemcheckbox"], namefrom:["author"], namerequired:!0, parent:["list", "select"]}, menubar:{namefrom:["author"], parent:["menu"]}, menuitem:{namefrom:["contents", "author"], namerequired:!0, parent:["command"]}, menuitemcheckbox:{namefrom:["contents", "author"], namerequired:!0, parent:["checkbox", "menuitem"]}, menuitemradio:{namefrom:["contents", "author"], namerequired:!0, parent:["menuitemcheckbox", "radio"]}, navigation:{namefrom:["author"], 
+parent:["landmark"]}, note:{namefrom:["author"], parent:["section"]}, option:{namefrom:["contents", "author"], namerequired:!0, parent:["input"], properties:["aria-checked", "aria-posinset", "aria-selected", "aria-setsize"]}, presentation:{parent:["structure"]}, progressbar:{childpresentational:!0, namefrom:["author"], namerequired:!0, parent:["range"]}, radio:{namefrom:["contents", "author"], namerequired:!0, parent:["checkbox", "option"]}, radiogroup:{mustcontain:["radio"], namefrom:["author"], 
+namerequired:!0, parent:["select"], properties:["aria-required"]}, range:{"abstract":!0, namefrom:["author"], parent:["widget"], properties:["aria-valuemax", "aria-valuemin", "aria-valuenow", "aria-valuetext"]}, region:{namefrom:[" author"], parent:["section"]}, roletype:{"abstract":!0, properties:"aria-atomic aria-busy aria-controls aria-describedby aria-disabled aria-dropeffect aria-flowto aria-grabbed aria-haspopup aria-hidden aria-invalid aria-label aria-labelledby aria-live aria-owns aria-relevant".split(" ")}, 
+row:{mustcontain:["columnheader", "gridcell", "rowheader"], namefrom:["contents", "author"], parent:["group", "widget"], properties:["aria-level", "aria-selected"]}, rowgroup:{mustcontain:["row"], namefrom:["contents", "author"], parent:["group"]}, rowheader:{namefrom:["contents", "author"], namerequired:!0, parent:["gridcell", "sectionhead", "widget"], properties:["aria-sort"]}, search:{namefrom:["author"], parent:["landmark"]}, section:{"abstract":!0, namefrom:["contents", "author"], parent:["structure"], 
+properties:["aria-expanded"]}, sectionhead:{"abstract":!0, namefrom:["contents", "author"], parent:["structure"], properties:["aria-expanded"]}, select:{"abstract":!0, namefrom:["author"], parent:["composite", "group", "input"]}, separator:{childpresentational:!0, namefrom:["author"], parent:["structure"], properties:["aria-expanded", "aria-orientation"]}, scrollbar:{childpresentational:!0, namefrom:["author"], namerequired:!1, parent:["input", "range"], requiredProperties:["aria-controls", "aria-orientation", 
+"aria-valuemax", "aria-valuemin", "aria-valuenow"], properties:["aria-controls", "aria-orientation", "aria-valuemax", "aria-valuemin", "aria-valuenow"]}, slider:{childpresentational:!0, namefrom:["author"], namerequired:!0, parent:["input", "range"], requiredProperties:["aria-valuemax", "aria-valuemin", "aria-valuenow"], properties:["aria-valuemax", "aria-valuemin", "aria-valuenow", "aria-orientation"]}, spinbutton:{namefrom:["author"], namerequired:!0, parent:["input", "range"], requiredProperties:["aria-valuemax", 
+"aria-valuemin", "aria-valuenow"], properties:["aria-valuemax", "aria-valuemin", "aria-valuenow", "aria-required"]}, status:{parent:["region"]}, structure:{"abstract":!0, parent:["roletype"]}, tab:{namefrom:["contents", "author"], parent:["sectionhead", "widget"], properties:["aria-selected"]}, tablist:{mustcontain:["tab"], namefrom:["author"], parent:["composite", "directory"], properties:["aria-level"]}, tabpanel:{namefrom:["author"], namerequired:!0, parent:["region"]}, textbox:{namefrom:["author"], 
+namerequired:!0, parent:["input"], properties:["aria-activedescendant", "aria-autocomplete", "aria-multiline", "aria-readonly", "aria-required"]}, timer:{namefrom:["author"], namerequired:!0, parent:["status"]}, toolbar:{namefrom:["author"], parent:["group"]}, tooltip:{namerequired:!0, parent:["section"]}, tree:{mustcontain:["group", "treeitem"], namefrom:["author"], namerequired:!0, parent:["select"], properties:["aria-multiselectable", "aria-required"]}, treegrid:{mustcontain:["row"], namefrom:["author"], 
+namerequired:!0, parent:["grid", "tree"]}, treeitem:{namefrom:["contents", "author"], namerequired:!0, parent:["listitem", "option"]}, widget:{"abstract":!0, parent:["roletype"]}, window:{"abstract":!0, namefrom:[" author"], parent:["roletype"], properties:["aria-expanded"]}};
 axs.constants.WIDGET_ROLES = {};
 axs.constants.addAllParentRolesToSet_ = function(a, b) {
   if (a.parent) {
@@ -481,18 +480,7 @@
 multiline:{defaultValue:"false", type:"property", valueType:"boolean"}, multiselectable:{defaultValue:"false", type:"property", valueType:"boolean"}, orientation:{defaultValue:"vertical", type:"property", valueType:"token", values:["horizontal", "vertical"]}, owns:{type:"property", valueType:"idref_list"}, posinset:{type:"property", valueType:"integer"}, pressed:{defaultValue:"undefined", type:"state", valueType:"token", values:["true", "false", "mixed", "undefined"]}, readonly:{defaultValue:"false", 
 type:"property", valueType:"boolean"}, relevant:{defaultValue:"additions text", type:"property", valueType:"token_list", values:["additions", "removals", "text", "all"]}, required:{defaultValue:"false", type:"property", valueType:"boolean"}, selected:{defaultValue:"undefined", type:"state", valueType:"token", values:["true", "false", "undefined"]}, setsize:{type:"property", valueType:"integer"}, sort:{defaultValue:"none", type:"property", valueType:"token", values:["ascending", "descending", "none", 
 "other"]}, valuemax:{type:"property", valueType:"decimal"}, valuemin:{type:"property", valueType:"decimal"}, valuenow:{type:"property", valueType:"decimal"}, valuetext:{type:"property", valueType:"string"}};
-(function() {
-  for (var a in axs.constants.ARIA_PROPERTIES) {
-    var b = axs.constants.ARIA_PROPERTIES[a];
-    if (b.values) {
-      for (var c = {}, d = 0;d < b.values.length;d++) {
-        c[b.values[d]] = !0;
-      }
-      b.valuesSet = c;
-    }
-  }
-})();
-axs.constants.GLOBAL_PROPERTIES = axs.constants.ARIA_ROLES.roletype.propertiesSet;
+axs.constants.GLOBAL_PROPERTIES = "aria-atomic aria-busy aria-controls aria-describedby aria-disabled aria-dropeffect aria-flowto aria-grabbed aria-haspopup aria-hidden aria-invalid aria-label aria-labelledby aria-live aria-owns aria-relevant".split(" ");
 axs.constants.NO_ROLE_NAME = " ";
 axs.constants.WIDGET_ROLE_TO_NAME = {alert:"aria_role_alert", alertdialog:"aria_role_alertdialog", button:"aria_role_button", checkbox:"aria_role_checkbox", columnheader:"aria_role_columnheader", combobox:"aria_role_combobox", dialog:"aria_role_dialog", grid:"aria_role_grid", gridcell:"aria_role_gridcell", link:"aria_role_link", listbox:"aria_role_listbox", log:"aria_role_log", marquee:"aria_role_marquee", menu:"aria_role_menu", menubar:"aria_role_menubar", menuitem:"aria_role_menuitem", menuitemcheckbox:"aria_role_menuitemcheckbox", 
 menuitemradio:"aria_role_menuitemradio", option:axs.constants.NO_ROLE_NAME, progressbar:"aria_role_progressbar", radio:"aria_role_radio", radiogroup:"aria_role_radiogroup", rowheader:"aria_role_rowheader", scrollbar:"aria_role_scrollbar", slider:"aria_role_slider", spinbutton:"aria_role_spinbutton", status:"aria_role_status", tab:"aria_role_tab", tabpanel:"aria_role_tabpanel", textbox:"aria_role_textbox", timer:"aria_role_timer", toolbar:"aria_role_toolbar", tooltip:"aria_role_tooltip", treeitem:"aria_role_treeitem"};
@@ -506,277 +494,80 @@
 axs.constants.TAG_TO_INFORMATION_TABLE_VERBOSE_MSG = {A:"tag_link", BUTTON:"tag_button", H1:"tag_h1", H2:"tag_h2", H3:"tag_h3", H4:"tag_h4", H5:"tag_h5", H6:"tag_h6", LI:"tag_li", OL:"tag_ol", SELECT:"tag_select", TEXTAREA:"tag_textarea", UL:"tag_ul", SECTION:"tag_section", NAV:"tag_nav", ARTICLE:"tag_article", ASIDE:"tag_aside", HGROUP:"tag_hgroup", HEADER:"tag_header", FOOTER:"tag_footer", TIME:"tag_time", MARK:"tag_mark"};
 axs.constants.TAG_TO_INFORMATION_TABLE_BRIEF_MSG = {BUTTON:"tag_button", SELECT:"tag_select", TEXTAREA:"tag_textarea"};
 axs.constants.MIXED_VALUES = {"true":!0, "false":!0, mixed:!0};
+(function() {
+  for (var a in axs.constants.ARIA_PROPERTIES) {
+    var b = axs.constants.ARIA_PROPERTIES[a];
+    if (b.values) {
+      for (var c = {}, d = 0;d < b.values.length;d++) {
+        c[b.values[d]] = !0;
+      }
+      b.valuesSet = c;
+    }
+  }
+})();
 axs.constants.Severity = {INFO:"Info", WARNING:"Warning", SEVERE:"Severe"};
 axs.constants.AuditResult = {PASS:"PASS", FAIL:"FAIL", NA:"NA"};
 axs.constants.InlineElements = {TT:!0, I:!0, B:!0, BIG:!0, SMALL:!0, EM:!0, STRONG:!0, DFN:!0, CODE:!0, SAMP:!0, KBD:!0, VAR:!0, CITE:!0, ABBR:!0, ACRONYM:!0, A:!0, IMG:!0, OBJECT:!0, BR:!0, SCRIPT:!0, MAP:!0, Q:!0, SUB:!0, SUP:!0, SPAN:!0, BDO:!0, INPUT:!0, SELECT:!0, TEXTAREA:!0, LABEL:!0, BUTTON:!0};
-axs.constants.NATIVELY_DISABLEABLE = {BUTTON:!0, INPUT:!0, SELECT:!0, TEXTAREA:!0, FIELDSET:!0, OPTGROUP:!0, OPTION:!0};
-axs.constants.ARIA_TO_HTML_ATTRIBUTE = {"aria-checked":"checked", "aria-disabled":"disabled", "aria-hidden":"hidden", "aria-expanded":"open", "aria-valuemax":"max", "aria-valuemin":"min", "aria-readonly":"readonly", "aria-required":"required", "aria-selected":"selected", "aria-valuenow":"value"};
-axs.constants.TAG_TO_IMPLICIT_SEMANTIC_INFO = {A:[{role:"link", allowed:"button checkbox menuitem menuitemcheckbox menuitemradio tab treeitem".split(" "), selector:"a[href]"}], ADDRESS:[{role:"", allowed:["contentinfo", "presentation"]}], AREA:[{role:"link", selector:"area[href]"}], ARTICLE:[{role:"article", allowed:["presentation", "article", "document", "application", "main"]}], ASIDE:[{role:"complementary", allowed:["note", "complementary", "search", "presentation"]}], AUDIO:[{role:"", allowed:["application", 
-"presentation"]}], BASE:[{role:"", reserved:!0}], BODY:[{role:"document", allowed:["presentation"]}], BUTTON:[{role:"button", allowed:["link", "menuitem", "menuitemcheckbox", "menuitemradio", "radio"], selector:'button:not([aria-pressed]):not([type="menu"])'}, {role:"button", allowed:["button"], selector:"button[aria-pressed]"}, {role:"button", attributes:{"aria-haspopup":!0}, allowed:["link", "menuitem", "menuitemcheckbox", "menuitemradio", "radio"], selector:'button[type="menu"]'}], CAPTION:[{role:"", 
-allowed:["presentation"]}], COL:[{role:"", reserved:!0}], COLGROUP:[{role:"", reserved:!0}], DATALIST:[{role:"listbox", attributes:{"aria-multiselectable":!1}, allowed:["presentation"]}], DEL:[{role:"", allowed:["*"]}], DD:[{role:"", allowed:["presentation"]}], DT:[{role:"", allowed:["presentation"]}], DETAILS:[{role:"group", allowed:["group", "presentation"]}], DIALOG:[{role:"dialog", allowed:"dialog alert alertdialog application log marquee status".split(" "), selector:"dialog[open]"}, {role:"dialog", 
-attributes:{"aria-hidden":!0}, allowed:"dialog alert alertdialog application log marquee status".split(" "), selector:"dialog:not([open])"}], DIV:[{role:"", allowed:["*"]}], DL:[{role:"list", allowed:["presentation"]}], EMBED:[{role:"", allowed:["application", "document", "img", "presentation"]}], FIGURE:[{role:"", allowed:["*"]}], FOOTER:[{role:"", allowed:["contentinfo", "presentation"]}], FORM:[{role:"form", allowed:["presentation"]}], P:[{role:"", allowed:["*"]}], PRE:[{role:"", allowed:["*"]}], 
-BLOCKQUOTE:[{role:"", allowed:["*"]}], H1:[{role:"heading"}], H2:[{role:"heading"}], H3:[{role:"heading"}], H4:[{role:"heading"}], H5:[{role:"heading"}], H6:[{role:"heading"}], HEAD:[{role:"", reserved:!0}], HEADER:[{role:"", allowed:["banner", "presentation"]}], HR:[{role:"separator", allowed:["presentation"]}], HTML:[{role:"", reserved:!0}], IFRAME:[{role:"", allowed:["application", "document", "img", "presentation"], selector:"iframe:not([seamless])"}, {role:"", allowed:["application", "document", 
-"img", "presentation", "group"], selector:"iframe[seamless]"}], IMG:[{role:"presentation", reserved:!0, selector:'img[alt=""]'}, {role:"img", allowed:["*"], selector:'img[alt]:not([alt=""])'}], INPUT:[{role:"button", allowed:["link", "menuitem", "menuitemcheckbox", "menuitemradio", "radio"], selector:'input[type="button"]:not([aria-pressed])'}, {role:"button", allowed:["button"], selector:'input[type="button"][aria-pressed]'}, {role:"checkbox", allowed:["checkbox"], selector:'input[type="checkbox"]'}, 
-{role:"", selector:'input[type="color"]'}, {role:"", selector:'input[type="date"]'}, {role:"", selector:'input[type="datetime"]'}, {role:"textbox", selector:'input[type="email"]:not([list])'}, {role:"", selector:'input[type="file"]'}, {role:"", reserved:!0, selector:'input[type="hidden"]'}, {role:"button", allowed:["button"], selector:'input[type="image"][aria-pressed]'}, {role:"button", allowed:["link", "menuitem", "menuitemcheckbox", "menuitemradio", "radio"], selector:'input[type="image"]:not([aria-pressed])'}, 
-{role:"", selector:'input[type="month"]'}, {role:"", selector:'input[type="number"]'}, {role:"textbox", selector:'input[type="password"]'}, {role:"radio", allowed:["menuitemradio"], selector:'input[type="radio"]'}, {role:"slider", selector:'input[type="range"]'}, {role:"button", selector:'input[type="reset"]'}, {role:"combobox", selector:'input[type="search"][list]'}, {role:"textbox", selector:'input[type="search"]:not([list])'}, {role:"button", selector:'input[type="submit"]'}, {role:"combobox", 
-selector:'input[type="tel"][list]'}, {role:"textbox", selector:'input[type="tel"]:not([list])'}, {role:"combobox", selector:'input[type="text"][list]'}, {role:"textbox", selector:'input[type="text"]:not([list])'}, {role:"textbox", selector:"input:not([type])"}, {role:"", selector:'input[type="time"]'}, {role:"combobox", selector:'input[type="url"][list]'}, {role:"textbox", selector:'input[type="url"]:not([list])'}, {role:"", selector:'input[type="week"]'}], INS:[{role:"", allowed:["*"]}], KEYGEN:[{role:""}], 
-LABEL:[{role:"", allowed:["presentation"]}], LI:[{role:"listitem", allowed:"menuitem menuitemcheckbox menuitemradio option tab treeitem presentation".split(" "), selector:'ol:not([role="presentation"])>li, ul:not([role="presentation"])>li'}, {role:"listitem", allowed:"listitem menuitem menuitemcheckbox menuitemradio option tab treeitem presentation".split(" "), selector:'ol[role="presentation"]>li, ul[role="presentation"]>li'}], LINK:[{role:"link", reserved:!0, selector:"link[href]"}], MAIN:[{role:"", 
-allowed:["main", "presentation"]}], MAP:[{role:"", reserved:!0}], MATH:[{role:"", allowed:["presentation"]}], MENU:[{role:"toolbar", selector:'menu[type="toolbar"]'}], MENUITEM:[{role:"menuitem", selector:'menuitem[type="command"]'}, {role:"menuitemcheckbox", selector:'menuitem[type="checkbox"]'}, {role:"menuitemradio", selector:'menuitem[type="radio"]'}], META:[{role:"", reserved:!0}], METER:[{role:"progressbar", allowed:["presentation"]}], NAV:[{role:"navigation", allowed:["navigation", "presentation"]}], 
-NOSCRIPT:[{role:"", reserved:!0}], OBJECT:[{role:"", allowed:["application", "document", "img", "presentation"]}], OL:[{role:"list", allowed:"directory group listbox menu menubar tablist toolbar tree presentation".split(" ")}], OPTGROUP:[{role:"", allowed:["presentation"]}], OPTION:[{role:"option"}], OUTPUT:[{role:"status", allowed:["*"]}], PARAM:[{role:"", reserved:!0}], PICTURE:[{role:"", reserved:!0}], PROGRESS:[{role:"progressbar", allowed:["presentation"]}], SCRIPT:[{role:"", reserved:!0}], 
-SECTION:[{role:"region", allowed:"alert alertdialog application contentinfo dialog document log marquee search status presentation".split(" ")}], SELECT:[{role:"listbox"}], SOURCE:[{role:"", reserved:!0}], SPAN:[{role:"", allowed:["*"]}], STYLE:[{role:"", reserved:!0}], SVG:[{role:"", allowed:["application", "document", "img", "presentation"]}], SUMMARY:[{role:"", allowed:["presentation"]}], TABLE:[{role:"", allowed:["*"]}], TEMPLATE:[{role:"", reserved:!0}], TEXTAREA:[{role:"textbox"}], TBODY:[{role:"rowgroup", 
-allowed:["*"]}], THEAD:[{role:"rowgroup", allowed:["*"]}], TFOOT:[{role:"rowgroup", allowed:["*"]}], TITLE:[{role:"", reserved:!0}], TD:[{role:"", allowed:["*"]}], TH:[{role:"", allowed:["*"]}], TR:[{role:"", allowed:["*"]}], TRACK:[{role:"", reserved:!0}], UL:[{role:"list", allowed:"directory group listbox menu menubar tablist toolbar tree presentation".split(" ")}], VIDEO:[{role:"", allowed:["application", "presentation"]}]};
-axs.color = {};
-axs.color.Color = function(a, b, c, d) {
+axs.utils = {};
+axs.utils.FOCUSABLE_ELEMENTS_SELECTOR = "input:not([type=hidden]):not([disabled]),select:not([disabled]),textarea:not([disabled]),button:not([disabled]),a[href],iframe,[tabindex]";
+axs.utils.Color = function(a, b, c, d) {
   this.red = a;
   this.green = b;
   this.blue = c;
   this.alpha = d;
 };
-axs.color.YCbCr = function(a) {
-  this.luma = this.z = a[0];
-  this.Cb = this.x = a[1];
-  this.Cr = this.y = a[2];
-};
-axs.color.YCbCr.prototype = {multiply:function(a) {
-  return new axs.color.YCbCr([this.luma * a, this.Cb * a, this.Cr * a]);
-}, add:function(a) {
-  return new axs.color.YCbCr([this.luma + a.luma, this.Cb + a.Cb, this.Cr + a.Cr]);
-}, subtract:function(a) {
-  return new axs.color.YCbCr([this.luma - a.luma, this.Cb - a.Cb, this.Cr - a.Cr]);
-}};
-axs.color.calculateContrastRatio = function(a, b) {
-  1 > a.alpha && (a = axs.color.flattenColors(a, b));
-  var c = axs.color.calculateLuminance(a), d = axs.color.calculateLuminance(b);
-  return (Math.max(c, d) + .05) / (Math.min(c, d) + .05);
-};
-axs.color.calculateLuminance = function(a) {
-  return axs.color.toYCbCr(a).luma;
-};
-axs.color.luminanceRatio = function(a, b) {
-  return (Math.max(a, b) + .05) / (Math.min(a, b) + .05);
-};
-axs.color.parseColor = function(a) {
-  if ("transparent" === a) {
-    return new axs.color.Color(0, 0, 0, 0);
+axs.utils.calculateContrastRatio = function(a, b) {
+  if (!a || !b) {
+    return null;
   }
-  var b = a.match(/^rgb\((\d+), (\d+), (\d+)\)$/);
+  1 > a.alpha && (a = axs.utils.flattenColors(a, b));
+  var c = axs.utils.calculateLuminance(a), d = axs.utils.calculateLuminance(b);
+  return(Math.max(c, d) + .05) / (Math.min(c, d) + .05);
+};
+axs.utils.luminanceRatio = function(a, b) {
+  return(Math.max(a, b) + .05) / (Math.min(a, b) + .05);
+};
+axs.utils.parentElement = function(a) {
+  if (!a) {
+    return null;
+  }
+  if (a.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+    return a.host;
+  }
+  var b = a.parentElement;
   if (b) {
-    a = parseInt(b[1], 10);
-    var c = parseInt(b[2], 10), d = parseInt(b[3], 10);
-    return new axs.color.Color(a, c, d, 1);
-  }
-  return (b = a.match(/^rgba\((\d+), (\d+), (\d+), (\d*(\.\d+)?)\)/)) ? (a = parseInt(b[1], 10), c = parseInt(b[2], 10), d = parseInt(b[3], 10), b = parseFloat(b[4]), new axs.color.Color(a, c, d, b)) : null;
-};
-axs.color.colorChannelToString = function(a) {
-  a = Math.round(a);
-  return 15 >= a ? "0" + a.toString(16) : a.toString(16);
-};
-axs.color.colorToString = function(a) {
-  return 1 == a.alpha ? "#" + axs.color.colorChannelToString(a.red) + axs.color.colorChannelToString(a.green) + axs.color.colorChannelToString(a.blue) : "rgba(" + [a.red, a.green, a.blue, a.alpha].join() + ")";
-};
-axs.color.luminanceFromContrastRatio = function(a, b, c) {
-  return c ? (a + .05) * b - .05 : (a + .05) / b - .05;
-};
-axs.color.translateColor = function(a, b) {
-  for (var c = b > a.luma ? axs.color.WHITE_YCC : axs.color.BLACK_YCC, d = c == axs.color.WHITE_YCC ? axs.color.YCC_CUBE_FACES_WHITE : axs.color.YCC_CUBE_FACES_BLACK, e = new axs.color.YCbCr([0, a.Cb, a.Cr]), f = new axs.color.YCbCr([1, a.Cb, a.Cr]), f = {a:e, b:f}, e = null, g = 0;g < d.length && !(e = axs.color.findIntersection(f, d[g]), 0 <= e.z && 1 >= e.z);g++) {
-  }
-  if (!e) {
-    throw "Couldn't find intersection with YCbCr color cube for Cb=" + a.Cb + ", Cr=" + a.Cr + ".";
-  }
-  if (e.x != a.x || e.y != a.y) {
-    throw "Intersection has wrong Cb/Cr values.";
-  }
-  if (Math.abs(c.luma - e.luma) < Math.abs(c.luma - b)) {
-    return c = [b, a.Cb, a.Cr], axs.color.fromYCbCrArray(c);
-  }
-  c = (b - e.luma) / (c.luma - e.luma);
-  c = [b, e.Cb - e.Cb * c, e.Cr - e.Cr * c];
-  return axs.color.fromYCbCrArray(c);
-};
-axs.color.suggestColors = function(a, b, c) {
-  var d = {}, e = axs.color.calculateLuminance(a), f = axs.color.calculateLuminance(b), g = f > e, h = axs.color.toYCbCr(b), k = axs.color.toYCbCr(a), m;
-  for (m in c) {
-    var l = c[m], n = axs.color.luminanceFromContrastRatio(e, l + .02, g);
-    if (1 >= n && 0 <= n) {
-      var p = axs.color.translateColor(h, n), l = axs.color.calculateContrastRatio(p, a), n = {};
-      n.fg = axs.color.colorToString(p);
-      n.bg = axs.color.colorToString(a);
-      n.contrast = l.toFixed(2);
-      d[m] = n;
-    } else {
-      l = axs.color.luminanceFromContrastRatio(f, l + .02, !g), 1 >= l && 0 <= l && (p = axs.color.translateColor(k, l), l = axs.color.calculateContrastRatio(b, p), n = {}, n.bg = axs.color.colorToString(p), n.fg = axs.color.colorToString(b), n.contrast = l.toFixed(2), d[m] = n);
-    }
-  }
-  return d;
-};
-axs.color.flattenColors = function(a, b) {
-  var c = a.alpha;
-  return new axs.color.Color((1 - c) * b.red + c * a.red, (1 - c) * b.green + c * a.green, (1 - c) * b.blue + c * a.blue, a.alpha + b.alpha * (1 - a.alpha));
-};
-axs.color.multiplyMatrixVector = function(a, b) {
-  var c = b[0], d = b[1], e = b[2];
-  return [a[0][0] * c + a[0][1] * d + a[0][2] * e, a[1][0] * c + a[1][1] * d + a[1][2] * e, a[2][0] * c + a[2][1] * d + a[2][2] * e];
-};
-axs.color.toYCbCr = function(a) {
-  var b = a.red / 255, c = a.green / 255;
-  a = a.blue / 255;
-  b = .03928 >= b ? b / 12.92 : Math.pow((b + .055) / 1.055, 2.4);
-  c = .03928 >= c ? c / 12.92 : Math.pow((c + .055) / 1.055, 2.4);
-  a = .03928 >= a ? a / 12.92 : Math.pow((a + .055) / 1.055, 2.4);
-  return new axs.color.YCbCr(axs.color.multiplyMatrixVector(axs.color.YCC_MATRIX, [b, c, a]));
-};
-axs.color.fromYCbCr = function(a) {
-  return axs.color.fromYCbCrArray([a.luma, a.Cb, a.Cr]);
-};
-axs.color.fromYCbCrArray = function(a) {
-  var b = axs.color.multiplyMatrixVector(axs.color.INVERTED_YCC_MATRIX, a), c = b[0];
-  a = b[1];
-  b = b[2];
-  c = .00303949 >= c ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - .055;
-  a = .00303949 >= a ? 12.92 * a : 1.055 * Math.pow(a, 1 / 2.4) - .055;
-  b = .00303949 >= b ? 12.92 * b : 1.055 * Math.pow(b, 1 / 2.4) - .055;
-  c = Math.min(Math.max(Math.round(255 * c), 0), 255);
-  a = Math.min(Math.max(Math.round(255 * a), 0), 255);
-  b = Math.min(Math.max(Math.round(255 * b), 0), 255);
-  return new axs.color.Color(c, a, b, 1);
-};
-axs.color.RGBToYCbCrMatrix = function(a, b) {
-  return [[a, 1 - a - b, b], [-a / (2 - 2 * b), (a + b - 1) / (2 - 2 * b), (1 - b) / (2 - 2 * b)], [(1 - a) / (2 - 2 * a), (a + b - 1) / (2 - 2 * a), -b / (2 - 2 * a)]];
-};
-axs.color.invert3x3Matrix = function(a) {
-  var b = a[0][0], c = a[0][1], d = a[0][2], e = a[1][0], f = a[1][1], g = a[1][2], h = a[2][0], k = a[2][1];
-  a = a[2][2];
-  return axs.color.scalarMultiplyMatrix([[f * a - g * k, d * k - c * a, c * g - d * f], [g * h - e * a, b * a - d * h, d * e - b * g], [e * k - f * h, h * c - b * k, b * f - c * e]], 1 / (b * (f * a - g * k) - c * (a * e - g * h) + d * (e * k - f * h)));
-};
-axs.color.findIntersection = function(a, b) {
-  var c = [a.a.x - b.p0.x, a.a.y - b.p0.y, a.a.z - b.p0.z], d = axs.color.invert3x3Matrix([[a.a.x - a.b.x, b.p1.x - b.p0.x, b.p2.x - b.p0.x], [a.a.y - a.b.y, b.p1.y - b.p0.y, b.p2.y - b.p0.y], [a.a.z - a.b.z, b.p1.z - b.p0.z, b.p2.z - b.p0.z]]), c = axs.color.multiplyMatrixVector(d, c)[0];
-  return a.a.add(a.b.subtract(a.a).multiply(c));
-};
-axs.color.scalarMultiplyMatrix = function(a, b) {
-  for (var c = [], d = 0;3 > d;d++) {
-    c[d] = axs.color.scalarMultiplyVector(a[d], b);
-  }
-  return c;
-};
-axs.color.scalarMultiplyVector = function(a, b) {
-  for (var c = [], d = 0;d < a.length;d++) {
-    c[d] = a[d] * b;
-  }
-  return c;
-};
-axs.color.kR = .2126;
-axs.color.kB = .0722;
-axs.color.YCC_MATRIX = axs.color.RGBToYCbCrMatrix(axs.color.kR, axs.color.kB);
-axs.color.INVERTED_YCC_MATRIX = axs.color.invert3x3Matrix(axs.color.YCC_MATRIX);
-axs.color.BLACK = new axs.color.Color(0, 0, 0, 1);
-axs.color.BLACK_YCC = axs.color.toYCbCr(axs.color.BLACK);
-axs.color.WHITE = new axs.color.Color(255, 255, 255, 1);
-axs.color.WHITE_YCC = axs.color.toYCbCr(axs.color.WHITE);
-axs.color.RED = new axs.color.Color(255, 0, 0, 1);
-axs.color.RED_YCC = axs.color.toYCbCr(axs.color.RED);
-axs.color.GREEN = new axs.color.Color(0, 255, 0, 1);
-axs.color.GREEN_YCC = axs.color.toYCbCr(axs.color.GREEN);
-axs.color.BLUE = new axs.color.Color(0, 0, 255, 1);
-axs.color.BLUE_YCC = axs.color.toYCbCr(axs.color.BLUE);
-axs.color.CYAN = new axs.color.Color(0, 255, 255, 1);
-axs.color.CYAN_YCC = axs.color.toYCbCr(axs.color.CYAN);
-axs.color.MAGENTA = new axs.color.Color(255, 0, 255, 1);
-axs.color.MAGENTA_YCC = axs.color.toYCbCr(axs.color.MAGENTA);
-axs.color.YELLOW = new axs.color.Color(255, 255, 0, 1);
-axs.color.YELLOW_YCC = axs.color.toYCbCr(axs.color.YELLOW);
-axs.color.YCC_CUBE_FACES_BLACK = [{p0:axs.color.BLACK_YCC, p1:axs.color.RED_YCC, p2:axs.color.GREEN_YCC}, {p0:axs.color.BLACK_YCC, p1:axs.color.GREEN_YCC, p2:axs.color.BLUE_YCC}, {p0:axs.color.BLACK_YCC, p1:axs.color.BLUE_YCC, p2:axs.color.RED_YCC}];
-axs.color.YCC_CUBE_FACES_WHITE = [{p0:axs.color.WHITE_YCC, p1:axs.color.CYAN_YCC, p2:axs.color.MAGENTA_YCC}, {p0:axs.color.WHITE_YCC, p1:axs.color.MAGENTA_YCC, p2:axs.color.YELLOW_YCC}, {p0:axs.color.WHITE_YCC, p1:axs.color.YELLOW_YCC, p2:axs.color.CYAN_YCC}];
-axs.dom = {};
-axs.dom.parentElement = function(a) {
-  if (!a) {
-    return null;
-  }
-  a = axs.dom.composedParentNode(a);
-  if (!a) {
-    return null;
-  }
-  switch(a.nodeType) {
-    case Node.ELEMENT_NODE:
-      return a;
-    default:
-      return axs.dom.parentElement(a);
-  }
-};
-axs.dom.shadowHost = function(a) {
-  return "host" in a ? a.host : null;
-};
-axs.dom.composedParentNode = function(a) {
-  if (!a) {
-    return null;
-  }
-  if (a.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
-    return axs.dom.shadowHost(a);
-  }
-  var b = a.parentNode;
-  if (!b) {
-    return null;
-  }
-  if (b.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
-    return axs.dom.shadowHost(b);
-  }
-  if (!b.shadowRoot) {
     return b;
   }
-  a = a.getDestinationInsertionPoints();
-  return 0 < a.length ? axs.dom.composedParentNode(a[a.length - 1]) : null;
-};
-axs.dom.asElement = function(a) {
+  a = a.parentNode;
+  if (!a) {
+    return null;
+  }
   switch(a.nodeType) {
-    case Node.COMMENT_NODE:
-      break;
     case Node.ELEMENT_NODE:
-      if ("script" == a.localName || "template" == a.localName) {
-        break;
-      }
       return a;
     case Node.DOCUMENT_FRAGMENT_NODE:
       return a.host;
-    case Node.TEXT_NODE:
-      return axs.dom.parentElement(a);
     default:
-      console.warn("Unhandled node type: ", a.nodeType);
+      return null;
   }
-  return null;
 };
-axs.dom.composedTreeSearch = function(a, b, c, d) {
-  if (a === b) {
-    return !0;
+axs.utils.asElement = function(a) {
+  switch(a.nodeType) {
+    case Node.COMMENT_NODE:
+      return null;
+    case Node.ELEMENT_NODE:
+      if ("script" == a.tagName.toLowerCase()) {
+        return null;
+      }
+      break;
+    case Node.TEXT_NODE:
+      a = axs.utils.parentElement(a);
+      break;
+    default:
+      return console.warn("Unhandled node type: ", a.nodeType), null;
   }
-  if (a.nodeType == Node.ELEMENT_NODE) {
-    var e = a
-  }
-  var f = !1;
-  if (e && c.preorder && !c.preorder(e)) {
-    return f;
-  }
-  if (e) {
-    var g = e.shadowRoot || e.webkitShadowRoot;
-    if (g) {
-      return f = axs.dom.composedTreeSearch(g, b, c, g), e && c.postorder && !f && c.postorder(e), f;
-    }
-  }
-  if (e && "content" == e.localName) {
-    a = e.getDistributedNodes();
-    for (g = 0;g < a.length && !f;g++) {
-      f = axs.dom.composedTreeSearch(a[g], b, c, d);
-    }
-    e && c.postorder && !f && c.postorder.call(null, e);
-    return f;
-  }
-  for (a = a.firstChild;null != a && !f;) {
-    f = axs.dom.composedTreeSearch(a, b, c, d), a = a.nextSibling;
-  }
-  e && c.postorder && !f && c.postorder.call(null, e);
-  return f;
+  return a;
 };
-axs.utils = {};
-axs.utils.FOCUSABLE_ELEMENTS_SELECTOR = "input:not([type=hidden]):not([disabled]),select:not([disabled]),textarea:not([disabled]),button:not([disabled]),a[href],iframe,[tabindex]";
-axs.utils.LABELABLE_ELEMENTS_SELECTOR = "button,input:not([type=hidden]),keygen,meter,output,progress,select,textarea";
 axs.utils.elementIsTransparent = function(a) {
   return "0" == a.style.opacity;
 };
@@ -786,45 +577,32 @@
   return a.right - a.left && b ? !1 : !0;
 };
 axs.utils.elementIsOutsideScrollArea = function(a) {
-  for (var b = axs.dom.parentElement(a), c = a.ownerDocument.defaultView;b != c.document.body;) {
+  for (var b = axs.utils.parentElement(a), c = a.ownerDocument.defaultView;b != c.document.body;) {
     if (axs.utils.isClippedBy(a, b)) {
-      return !0;
+      return!0;
     }
     if (axs.utils.canScrollTo(a, b) && !axs.utils.elementIsOutsideScrollArea(b)) {
-      return !1;
+      return!1;
     }
-    b = axs.dom.parentElement(b);
+    b = axs.utils.parentElement(b);
   }
-  return !axs.utils.canScrollTo(a, c.document.body);
+  return!axs.utils.canScrollTo(a, c.document.body);
 };
 axs.utils.canScrollTo = function(a, b) {
-  var c = a.getBoundingClientRect(), d = b.getBoundingClientRect();
-  if (b == b.ownerDocument.body) {
-    var e = d.top, f = d.left
-  } else {
-    e = d.top - b.scrollTop, f = d.left - b.scrollLeft;
+  var c = a.getBoundingClientRect(), d = b.getBoundingClientRect(), e = d.top, f = d.left, g = e - b.scrollTop, e = e - b.scrollTop + b.scrollHeight, h = f - b.scrollLeft + b.scrollWidth;
+  if (c.right < f - b.scrollLeft || c.bottom < g || c.left > h || c.top > e) {
+    return!1;
   }
-  var g = e + b.scrollHeight, h = f + b.scrollWidth;
-  if (c.right < f || c.bottom < e || c.left > h || c.top > g) {
-    return !1;
-  }
-  e = a.ownerDocument.defaultView;
-  f = e.getComputedStyle(b);
-  return c.left > d.right || c.top > d.bottom ? "scroll" == f.overflow || "auto" == f.overflow || b instanceof e.HTMLBodyElement : !0;
+  f = a.ownerDocument.defaultView;
+  g = f.getComputedStyle(b);
+  return c.left > d.right || c.top > d.bottom ? "scroll" == g.overflow || "auto" == g.overflow || b instanceof f.HTMLBodyElement : !0;
 };
 axs.utils.isClippedBy = function(a, b) {
   var c = a.getBoundingClientRect(), d = b.getBoundingClientRect(), e = d.top - b.scrollTop, f = d.left - b.scrollLeft, g = a.ownerDocument.defaultView.getComputedStyle(b);
-  return (c.right < d.left || c.bottom < d.top || c.left > d.right || c.top > d.bottom) && "hidden" == g.overflow ? !0 : c.right < f || c.bottom < e ? "visible" != g.overflow : !1;
+  return(c.right < d.left || c.bottom < d.top || c.left > d.right || c.top > d.bottom) && "hidden" == g.overflow ? !0 : c.right < f || c.bottom < e ? "visible" != g.overflow : !1;
 };
 axs.utils.isAncestor = function(a, b) {
-  if (null == b) {
-    return !1;
-  }
-  if (b === a) {
-    return !0;
-  }
-  var c = axs.dom.composedParentNode(b);
-  return axs.utils.isAncestor(a, c);
+  return null == b ? !1 : b === a ? !0 : axs.utils.isAncestor(a, b.parentNode);
 };
 axs.utils.overlappingElements = function(a) {
   if (axs.utils.elementHasZeroArea(a)) {
@@ -870,13 +648,13 @@
   }
   if (c = b.match(/(\d+)pt/)) {
     if (b = parseInt(c[1], 10), a && 14 <= b || 18 <= b) {
-      return !0;
+      return!0;
     }
   }
-  return !1;
+  return!1;
 };
 axs.utils.getBgColor = function(a, b) {
-  var c = axs.color.parseColor(a.backgroundColor);
+  var c = axs.utils.parseColor(a.backgroundColor);
   if (!c) {
     return null;
   }
@@ -886,38 +664,158 @@
     if (null == d) {
       return null;
     }
-    c = axs.color.flattenColors(c, d);
+    c = axs.utils.flattenColors(c, d);
   }
   return c;
 };
 axs.utils.getParentBgColor = function(a) {
   var b = a;
   a = [];
-  for (var c = null;b = axs.dom.parentElement(b);) {
+  for (var c = null;b = axs.utils.parentElement(b);) {
     var d = window.getComputedStyle(b, null);
     if (d) {
-      var e = axs.color.parseColor(d.backgroundColor);
+      var e = axs.utils.parseColor(d.backgroundColor);
       if (e && (1 > d.opacity && (e.alpha *= d.opacity), 0 != e.alpha && (a.push(e), 1 == e.alpha))) {
         c = !0;
         break;
       }
     }
   }
-  c || a.push(new axs.color.Color(255, 255, 255, 1));
+  c || a.push(new axs.utils.Color(255, 255, 255, 1));
   for (b = a.pop();a.length;) {
-    c = a.pop(), b = axs.color.flattenColors(c, b);
+    c = a.pop(), b = axs.utils.flattenColors(c, b);
   }
   return b;
 };
 axs.utils.getFgColor = function(a, b, c) {
-  var d = axs.color.parseColor(a.color);
+  var d = axs.utils.parseColor(a.color);
   if (!d) {
     return null;
   }
-  1 > d.alpha && (d = axs.color.flattenColors(d, c));
-  1 > a.opacity && (b = axs.utils.getParentBgColor(b), d.alpha *= a.opacity, d = axs.color.flattenColors(d, b));
+  1 > d.alpha && (d = axs.utils.flattenColors(d, c));
+  1 > a.opacity && (b = axs.utils.getParentBgColor(b), d.alpha *= a.opacity, d = axs.utils.flattenColors(d, b));
   return d;
 };
+axs.utils.parseColor = function(a) {
+  var b = a.match(/^rgb\((\d+), (\d+), (\d+)\)$/);
+  if (b) {
+    a = parseInt(b[1], 10);
+    var c = parseInt(b[2], 10), b = parseInt(b[3], 10), d;
+    return new axs.utils.Color(a, c, b, 1);
+  }
+  return(b = a.match(/^rgba\((\d+), (\d+), (\d+), (\d+(\.\d+)?)\)/)) ? (d = parseInt(b[4], 10), a = parseInt(b[1], 10), c = parseInt(b[2], 10), b = parseInt(b[3], 10), new axs.utils.Color(a, c, b, d)) : null;
+};
+axs.utils.colorChannelToString = function(a) {
+  a = Math.round(a);
+  return 15 >= a ? "0" + a.toString(16) : a.toString(16);
+};
+axs.utils.colorToString = function(a) {
+  return 1 == a.alpha ? "#" + axs.utils.colorChannelToString(a.red) + axs.utils.colorChannelToString(a.green) + axs.utils.colorChannelToString(a.blue) : "rgba(" + [a.red, a.green, a.blue, a.alpha].join() + ")";
+};
+axs.utils.luminanceFromContrastRatio = function(a, b, c) {
+  return c ? (a + .05) * b - .05 : (a + .05) / b - .05;
+};
+axs.utils.translateColor = function(a, b) {
+  var c = a[0], c = (b - c) / ((c > b ? 0 : 1) - c);
+  return axs.utils.fromYCC([b, a[1] - a[1] * c, a[2] - a[2] * c]);
+};
+axs.utils.suggestColors = function(a, b, c, d) {
+  if (!axs.utils.isLowContrast(c, d, !0)) {
+    return null;
+  }
+  var e = {}, f = axs.utils.calculateLuminance(a), g = axs.utils.calculateLuminance(b), h = axs.utils.isLargeFont(d) ? 3 : 4.5, k = axs.utils.isLargeFont(d) ? 4.5 : 7, m = g > f, l = axs.utils.luminanceFromContrastRatio(f, h + .02, m), n = axs.utils.luminanceFromContrastRatio(f, k + .02, m), q = axs.utils.toYCC(b);
+  if (axs.utils.isLowContrast(c, d, !1) && 1 >= l && 0 <= l) {
+    var p = axs.utils.translateColor(q, l), l = axs.utils.calculateContrastRatio(p, a);
+    axs.utils.calculateLuminance(p);
+    f = {};
+    f.fg = axs.utils.colorToString(p);
+    f.bg = axs.utils.colorToString(a);
+    f.contrast = l.toFixed(2);
+    e.AA = f;
+  }
+  axs.utils.isLowContrast(c, d, !0) && 1 >= n && 0 <= n && (n = axs.utils.translateColor(q, n), l = axs.utils.calculateContrastRatio(n, a), f = {}, f.fg = axs.utils.colorToString(n), f.bg = axs.utils.colorToString(a), f.contrast = l.toFixed(2), e.AAA = f);
+  h = axs.utils.luminanceFromContrastRatio(g, h + .02, !m);
+  g = axs.utils.luminanceFromContrastRatio(g, k + .02, !m);
+  a = axs.utils.toYCC(a);
+  !("AA" in e) && axs.utils.isLowContrast(c, d, !1) && 1 >= h && 0 <= h && (k = axs.utils.translateColor(a, h), l = axs.utils.calculateContrastRatio(b, k), f = {}, f.bg = axs.utils.colorToString(k), f.fg = axs.utils.colorToString(b), f.contrast = l.toFixed(2), e.AA = f);
+  !("AAA" in e) && axs.utils.isLowContrast(c, d, !0) && 1 >= g && 0 <= g && (c = axs.utils.translateColor(a, g), l = axs.utils.calculateContrastRatio(b, c), f = {}, f.bg = axs.utils.colorToString(c), f.fg = axs.utils.colorToString(b), f.contrast = l.toFixed(2), e.AAA = f);
+  return e;
+};
+axs.utils.flattenColors = function(a, b) {
+  var c = a.alpha;
+  return new axs.utils.Color((1 - c) * b.red + c * a.red, (1 - c) * b.green + c * a.green, (1 - c) * b.blue + c * a.blue, a.alpha + b.alpha * (1 - a.alpha));
+};
+axs.utils.calculateLuminance = function(a) {
+  return axs.utils.toYCC(a)[0];
+};
+axs.utils.RGBToYCCMatrix = function(a, b) {
+  return[[a, 1 - a - b, b], [-a / (2 - 2 * b), (a + b - 1) / (2 - 2 * b), (1 - b) / (2 - 2 * b)], [(1 - a) / (2 - 2 * a), (a + b - 1) / (2 - 2 * a), -b / (2 - 2 * a)]];
+};
+axs.utils.invert3x3Matrix = function(a) {
+  var b = a[0][0], c = a[0][1], d = a[0][2], e = a[1][0], f = a[1][1], g = a[1][2], h = a[2][0], k = a[2][1];
+  a = a[2][2];
+  return axs.utils.scalarMultiplyMatrix([[f * a - g * k, d * k - c * a, c * g - d * f], [g * h - e * a, b * a - d * h, d * e - b * g], [e * k - f * h, h * c - b * k, b * f - c * e]], 1 / (b * (f * a - g * k) - c * (a * e - g * h) + d * (e * k - f * h)));
+};
+axs.utils.scalarMultiplyMatrix = function(a, b) {
+  for (var c = [[], [], []], d = 0;3 > d;d++) {
+    for (var e = 0;3 > e;e++) {
+      c[d][e] = a[d][e] * b;
+    }
+  }
+  return c;
+};
+axs.utils.kR = .2126;
+axs.utils.kB = .0722;
+axs.utils.YCC_MATRIX = axs.utils.RGBToYCCMatrix(axs.utils.kR, axs.utils.kB);
+axs.utils.INVERTED_YCC_MATRIX = axs.utils.invert3x3Matrix(axs.utils.YCC_MATRIX);
+axs.utils.convertColor = function(a, b) {
+  var c = b[0], d = b[1], e = b[2];
+  return[a[0][0] * c + a[0][1] * d + a[0][2] * e, a[1][0] * c + a[1][1] * d + a[1][2] * e, a[2][0] * c + a[2][1] * d + a[2][2] * e];
+};
+axs.utils.multiplyMatrices = function(a, b) {
+  for (var c = [[], [], []], d = 0;3 > d;d++) {
+    for (var e = 0;3 > e;e++) {
+      c[d][e] = a[d][0] * b[0][e] + a[d][1] * b[1][e] + a[d][2] * b[2][e];
+    }
+  }
+  return c;
+};
+axs.utils.toYCC = function(a) {
+  var b = a.red / 255, c = a.green / 255;
+  a = a.blue / 255;
+  b = .03928 >= b ? b / 12.92 : Math.pow((b + .055) / 1.055, 2.4);
+  c = .03928 >= c ? c / 12.92 : Math.pow((c + .055) / 1.055, 2.4);
+  a = .03928 >= a ? a / 12.92 : Math.pow((a + .055) / 1.055, 2.4);
+  return axs.utils.convertColor(axs.utils.YCC_MATRIX, [b, c, a]);
+};
+axs.utils.fromYCC = function(a) {
+  var b = axs.utils.convertColor(axs.utils.INVERTED_YCC_MATRIX, a), c = b[0];
+  a = b[1];
+  b = b[2];
+  c = .00303949 >= c ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - .055;
+  a = .00303949 >= a ? 12.92 * a : 1.055 * Math.pow(a, 1 / 2.4) - .055;
+  b = .00303949 >= b ? 12.92 * b : 1.055 * Math.pow(b, 1 / 2.4) - .055;
+  c = Math.min(Math.max(Math.round(255 * c), 0), 255);
+  a = Math.min(Math.max(Math.round(255 * a), 0), 255);
+  b = Math.min(Math.max(Math.round(255 * b), 0), 255);
+  return new axs.utils.Color(c, a, b, 1);
+};
+axs.utils.scalarMultiplyMatrix = function(a, b) {
+  for (var c = [[], [], []], d = 0;3 > d;d++) {
+    for (var e = 0;3 > e;e++) {
+      c[d][e] = a[d][e] * b;
+    }
+  }
+  return c;
+};
+axs.utils.multiplyMatrices = function(a, b) {
+  for (var c = [[], [], []], d = 0;3 > d;d++) {
+    for (var e = 0;3 > e;e++) {
+      c[d][e] = a[d][0] * b[0][e] + a[d][1] * b[1][e] + a[d][2] * b[2][e];
+    }
+  }
+  return c;
+};
 axs.utils.getContrastRatioForElement = function(a) {
   var b = window.getComputedStyle(a, null);
   return axs.utils.getContrastRatioForElementWithComputedStyle(b, a);
@@ -931,16 +829,16 @@
     return null;
   }
   var d = axs.utils.getFgColor(a, b, c);
-  return d ? axs.color.calculateContrastRatio(d, c) : null;
+  return d ? axs.utils.calculateContrastRatio(d, c) : null;
 };
 axs.utils.isNativeTextElement = function(a) {
   var b = a.tagName.toLowerCase();
   a = a.type ? a.type.toLowerCase() : "";
   if ("textarea" == b) {
-    return !0;
+    return!0;
   }
   if ("input" != b) {
-    return !1;
+    return!1;
   }
   switch(a) {
     case "email":
@@ -958,9 +856,9 @@
     case "url":
     ;
     case "":
-      return !0;
+      return!0;
     default:
-      return !1;
+      return!1;
   }
 };
 axs.utils.isLowContrast = function(a, b, c) {
@@ -969,37 +867,20 @@
 };
 axs.utils.hasLabel = function(a) {
   var b = a.tagName.toLowerCase(), c = a.type ? a.type.toLowerCase() : "";
-  if (a.hasAttribute("aria-label") || a.hasAttribute("title") || "img" == b && a.hasAttribute("alt") || "input" == b && "image" == c && a.hasAttribute("alt") || "input" == b && ("submit" == c || "reset" == c) || a.hasAttribute("aria-labelledby") || a.hasAttribute("id") && 0 < document.querySelectorAll('label[for="' + a.id + '"]').length) {
-    return !0;
+  if (a.hasAttribute("aria-label") || a.hasAttribute("title") || "img" == b && a.hasAttribute("alt") || "input" == b && "image" == c && a.hasAttribute("alt") || "input" == b && ("submit" == c || "reset" == c) || a.hasAttribute("aria-labelledby") || axs.utils.isNativeTextElement(a) && a.hasAttribute("placeholder") || a.hasAttribute("id") && 0 < document.querySelectorAll('label[for="' + a.id + '"]').length) {
+    return!0;
   }
-  for (b = axs.dom.parentElement(a);b;) {
+  for (b = axs.utils.parentElement(a);b;) {
     if ("label" == b.tagName.toLowerCase() && b.control == a) {
-      return !0;
+      return!0;
     }
-    b = axs.dom.parentElement(b);
+    b = axs.utils.parentElement(b);
   }
-  return !1;
-};
-axs.utils.isNativelyDisableable = function(a) {
-  return a.tagName.toUpperCase() in axs.constants.NATIVELY_DISABLEABLE;
-};
-axs.utils.isElementDisabled = function(a) {
-  if (axs.browserUtils.matchSelector(a, "[aria-disabled=true], [aria-disabled=true] *")) {
-    return !0;
-  }
-  if (!axs.utils.isNativelyDisableable(a) || axs.browserUtils.matchSelector(a, "fieldset>legend:first-of-type *")) {
-    return !1;
-  }
-  for (;null !== a;a = axs.dom.parentElement(a)) {
-    if (axs.utils.isNativelyDisableable(a) && a.hasAttribute("disabled")) {
-      return !0;
-    }
-  }
-  return !1;
+  return!1;
 };
 axs.utils.isElementHidden = function(a) {
   if (!(a instanceof a.ownerDocument.defaultView.HTMLElement)) {
-    return !1;
+    return!1;
   }
   if (a.hasAttribute("chromevoxignoreariahidden")) {
     var b = !0
@@ -1008,27 +889,22 @@
   return "none" == c.display || "hidden" == c.visibility ? !0 : a.hasAttribute("aria-hidden") && "true" == a.getAttribute("aria-hidden").toLowerCase() ? !b : !1;
 };
 axs.utils.isElementOrAncestorHidden = function(a) {
-  return axs.utils.isElementHidden(a) ? !0 : axs.dom.parentElement(a) ? axs.utils.isElementOrAncestorHidden(axs.dom.parentElement(a)) : !1;
+  return axs.utils.isElementHidden(a) ? !0 : axs.utils.parentElement(a) ? axs.utils.isElementOrAncestorHidden(axs.utils.parentElement(a)) : !1;
 };
 axs.utils.isInlineElement = function(a) {
   a = a.tagName.toUpperCase();
   return axs.constants.InlineElements[a];
 };
-axs.utils.getRoles = function(a, b) {
-  if (!a || a.nodeType !== Node.ELEMENT_NODE || !a.hasAttribute("role") && !b) {
-    return null;
+axs.utils.getRoles = function(a) {
+  if (!a.hasAttribute("role")) {
+    return!1;
   }
-  var c = a.getAttribute("role");
-  !c && b && (c = axs.properties.getImplicitRole(a));
-  if (!c) {
-    return null;
+  a = a.getAttribute("role").split(" ");
+  for (var b = [], c = !0, d = 0;d < a.length;d++) {
+    var e = a[d];
+    axs.constants.ARIA_ROLES[e] ? b.push({name:e, details:axs.constants.ARIA_ROLES[e], valid:!0}) : (b.push({name:e, valid:!1}), c = !1);
   }
-  for (var c = c.split(" "), d = {roles:[], valid:!1}, e = 0;e < c.length;e++) {
-    var f = c[e], g = axs.constants.ARIA_ROLES[f], f = {name:f};
-    g && !g.abstract ? (f.details = g, d.applied || (d.applied = f), f.valid = d.valid = !0) : f.valid = !1;
-    d.roles.push(f);
-  }
-  return d;
+  return{roles:b, valid:c};
 };
 axs.utils.getAriaPropertyValue = function(a, b, c) {
   var d = a.replace(/^aria-/, ""), e = axs.constants.ARIA_PROPERTIES[d], d = {name:a, rawValue:b};
@@ -1050,22 +926,16 @@
       }
       return d;
     case "integer":
+    ;
+    case "decimal":
       c = axs.utils.isValidNumber(b);
       if (!c.valid) {
         return d.valid = !1, d.reason = c.reason, d;
       }
-      Math.floor(c.value) !== c.value ? (d.valid = !1, d.reason = "" + b + " is not a whole integer") : (d.valid = !0, d.value = c.value);
+      Math.floor(c.value) != c.value ? (d.valid = !1, d.reason = "" + b + " is not a whole integer") : (d.valid = !0, d.value = c.value);
       return d;
-    case "decimal":
-    ;
     case "number":
-      c = axs.utils.isValidNumber(b);
-      d.valid = c.valid;
-      if (!c.valid) {
-        return d.reason = c.reason, d;
-      }
-      d.value = c.value;
-      return d;
+      c = axs.utils.isValidNumber(b), c.valid && (d.valid = !0, d.value = c.value);
     case "string":
       return d.valid = !0, d.value = b, d;
     case "token":
@@ -1105,15 +975,12 @@
   return 0 == a.length ? {valid:!0, idref:a} : b.ownerDocument.getElementById(a) ? {valid:!0, idref:a} : {valid:!1, idref:a, reason:'No element with ID "' + a + '"'};
 };
 axs.utils.isValidNumber = function(a) {
-  var b = {valid:!1, value:a, reason:'"' + a + '" is not a number'};
-  if (!a) {
-    return b;
+  try {
+    var b = JSON.parse(a);
+  } catch (c) {
+    return{valid:!1, value:a, reason:'"' + a + '" is not a number'};
   }
-  if (/^0x/i.test(a)) {
-    return b.reason = '"' + a + '" is not a decimal number', b;
-  }
-  a *= 1;
-  return isFinite(a) ? {valid:!0, value:a} : b;
+  return "number" != typeof b ? {valid:!1, value:a, reason:'"' + a + '" is not a number'} : {valid:!0, value:b};
 };
 axs.utils.isElementImplicitlyFocusable = function(a) {
   var b = a.ownerDocument.defaultView;
@@ -1160,9 +1027,7 @@
       } else {
         d = 1;
       }
-      if (1 == d) {
-        return axs.utils.getQuerySelectorText(a.parentNode) + " > " + b;
-      }
+      return 1 == d ? axs.utils.getQuerySelectorText(a.parentNode) + " > " + b : axs.utils.getQuerySelectorText(a.parentNode) + " > " + b + ":nth-of-type(" + d + ")";
     }
     if (a.parentNode) {
       b = a.parentNode.children;
@@ -1181,103 +1046,6 @@
   }
   return "";
 };
-axs.utils.getAriaIdReferrers = function(a, b) {
-  var c = function(a) {
-    var b = axs.constants.ARIA_PROPERTIES[a];
-    if (b) {
-      if ("idref" === b.valueType) {
-        return "[aria-" + a + "='" + d + "']";
-      }
-      if ("idref_list" === b.valueType) {
-        return "[aria-" + a + "~='" + d + "']";
-      }
-    }
-    return "";
-  };
-  if (!a) {
-    return null;
-  }
-  var d = a.id;
-  if (!d) {
-    return null;
-  }
-  d = d.replace(/'/g, "\\'");
-  if (b) {
-    var e = b.replace(/^aria-/, ""), f = c(e);
-    if (f) {
-      return a.ownerDocument.querySelectorAll(f);
-    }
-  } else {
-    var g = [];
-    for (e in axs.constants.ARIA_PROPERTIES) {
-      (f = c(e)) && g.push(f);
-    }
-    return a.ownerDocument.querySelectorAll(g.join(","));
-  }
-  return null;
-};
-axs.utils.getHtmlIdReferrers = function(a) {
-  if (!a) {
-    return null;
-  }
-  var b = a.id;
-  if (!b) {
-    return null;
-  }
-  var b = b.replace(/'/g, "\\'"), c = "[contextmenu='{id}'] [itemref~='{id}'] button[form='{id}'] button[menu='{id}'] fieldset[form='{id}'] input[form='{id}'] input[list='{id}'] keygen[form='{id}'] label[for='{id}'] label[form='{id}'] menuitem[command='{id}'] object[form='{id}'] output[for~='{id}'] output[form='{id}'] select[form='{id}'] td[headers~='{id}'] textarea[form='{id}'] tr[headers~='{id}']".split(" ").map(function(a) {
-    return a.replace("{id}", b);
-  });
-  return a.ownerDocument.querySelectorAll(c.join(","));
-};
-axs.utils.getIdReferrers = function(a) {
-  var b = [], c = axs.utils.getHtmlIdReferrers(a);
-  c && (b = b.concat(Array.prototype.slice.call(c)));
-  (c = axs.utils.getAriaIdReferrers(a)) && (b = b.concat(Array.prototype.slice.call(c)));
-  return b;
-};
-axs.utils.getIdReferents = function(a, b) {
-  var c = [], d = a.replace(/^aria-/, ""), d = axs.constants.ARIA_PROPERTIES[d];
-  if (!d || !b.hasAttribute(a)) {
-    return c;
-  }
-  d = d.valueType;
-  if ("idref_list" === d || "idref" === d) {
-    for (var d = b.ownerDocument, e = b.getAttribute(a), e = e.split(/\s+/), f = 0, g = e.length;f < g;f++) {
-      var h = d.getElementById(e[f]);
-      h && (c[c.length] = h);
-    }
-  }
-  return c;
-};
-axs.utils.getAriaPropertiesByValueType = function(a) {
-  var b = {}, c;
-  for (c in axs.constants.ARIA_PROPERTIES) {
-    var d = axs.constants.ARIA_PROPERTIES[c];
-    d && 0 <= a.indexOf(d.valueType) && (b[c] = d);
-  }
-  return b;
-};
-axs.utils.getSelectorForAriaProperties = function(a) {
-  a = Object.keys(a).map(function(a) {
-    return "[aria-" + a + "]";
-  });
-  a.sort();
-  return a.join(",");
-};
-axs.utils.findDescendantsWithRole = function(a, b) {
-  if (!a || !b) {
-    return [];
-  }
-  var c = axs.properties.getSelectorForRole(b);
-  if (c && (c = a.querySelectorAll(c))) {
-    c = Array.prototype.map.call(c, function(a) {
-      return a;
-    });
-  } else {
-    return [];
-  }
-  return c;
-};
 axs.properties = {};
 axs.properties.TEXT_CONTENT_XPATH = './/text()[normalize-space(.)!=""]/parent::*[name()!="script"]';
 axs.properties.getFocusProperties = function(a) {
@@ -1310,7 +1078,7 @@
     var b = !0
   }
   var c = window.getComputedStyle(a, null);
-  return "none" == c.display ? {property:"display: none", on:a} : "hidden" == c.visibility ? {property:"visibility: hidden", on:a} : a.hasAttribute("aria-hidden") && "true" == a.getAttribute("aria-hidden").toLowerCase() && !b ? {property:"aria-hidden", on:a} : axs.properties.getHiddenReason(axs.dom.parentElement(a));
+  return "none" == c.display ? {property:"display: none", on:a} : "hidden" == c.visibility ? {property:"visibility: hidden", on:a} : a.hasAttribute("aria-hidden") && "true" == a.getAttribute("aria-hidden").toLowerCase() && !b ? {property:"aria-hidden", on:a} : axs.properties.getHiddenReason(axs.utils.parentElement(a));
 };
 axs.properties.getColorProperties = function(a) {
   var b = {};
@@ -1318,25 +1086,13 @@
   return 0 == Object.keys(b).length ? null : b;
 };
 axs.properties.hasDirectTextDescendant = function(a) {
-  function b() {
-    for (var b = c.evaluate(axs.properties.TEXT_CONTENT_XPATH, a, null, XPathResult.ANY_TYPE, null), e = b.iterateNext();null != e;e = b.iterateNext()) {
-      if (e === a) {
-        return !0;
-      }
+  for (var b = (a.nodeType == Node.DOCUMENT_NODE ? a : a.ownerDocument).evaluate(axs.properties.TEXT_CONTENT_XPATH, a, null, XPathResult.ANY_TYPE, null), c = !1, d = b.iterateNext();null != d;d = b.iterateNext()) {
+    if (d === a) {
+      c = !0;
+      break;
     }
-    return !1;
   }
-  var c;
-  c = a.nodeType == Node.DOCUMENT_NODE ? a : a.ownerDocument;
-  return c.evaluate ? b() : function() {
-    for (var b = c.createTreeWalker(a, NodeFilter.SHOW_TEXT, null, !1);b.nextNode();) {
-      var e = b.currentNode, f = e.parentNode.tagName.toLowerCase();
-      if (e.nodeValue.trim() && "script" !== f && a !== e) {
-        return !0;
-      }
-    }
-    return !1;
-  }();
+  return c;
 };
 axs.properties.getContrastRatioProperties = function(a) {
   if (!axs.properties.hasDirectTextDescendant(a)) {
@@ -1346,28 +1102,22 @@
   if (!d) {
     return null;
   }
-  b.backgroundColor = axs.color.colorToString(d);
+  b.backgroundColor = axs.utils.colorToString(d);
   var e = axs.utils.getFgColor(c, a, d);
-  b.foregroundColor = axs.color.colorToString(e);
+  b.foregroundColor = axs.utils.colorToString(e);
   a = axs.utils.getContrastRatioForElementWithComputedStyle(c, a);
   if (!a) {
     return null;
   }
   b.value = a.toFixed(2);
   axs.utils.isLowContrast(a, c) && (b.alert = !0);
-  var f = axs.utils.isLargeFont(c) ? 3 : 4.5, c = axs.utils.isLargeFont(c) ? 4.5 : 7, g = {};
-  f > a && (g.AA = f);
-  c > a && (g.AAA = c);
-  if (!Object.keys(g).length) {
-    return b;
-  }
-  (d = axs.color.suggestColors(d, e, g)) && Object.keys(d).length && (b.suggestedColors = d);
+  (c = axs.utils.suggestColors(d, e, a, c)) && Object.keys(c).length && (b.suggestedColors = c);
   return b;
 };
 axs.properties.findTextAlternatives = function(a, b, c, d) {
   var e = c || !1;
-  c = axs.dom.asElement(a);
-  if (!c || !d && axs.utils.isElementOrAncestorHidden(c)) {
+  c = axs.utils.asElement(a);
+  if (!c || !e && !d && axs.utils.isElementOrAncestorHidden(c)) {
     return null;
   }
   if (a.nodeType == Node.TEXT_NODE) {
@@ -1375,23 +1125,17 @@
   }
   a = null;
   e || (a = axs.properties.getTextFromAriaLabelledby(c, b));
-  if (c.hasAttribute("aria-label")) {
-    var f = {type:"text"};
-    f.text = c.getAttribute("aria-label");
-    f.lastWord = axs.properties.getLastWord(f.text);
-    a ? f.unused = !0 : e && axs.utils.elementIsHtmlControl(c) || (a = f.text);
-    b.ariaLabel = f;
-  }
+  c.hasAttribute("aria-label") && (d = {type:"text"}, d.text = c.getAttribute("aria-label"), d.lastWord = axs.properties.getLastWord(d.text), a ? d.unused = !0 : e && axs.utils.elementIsHtmlControl(c) || (a = d.text), b.ariaLabel = d);
   c.hasAttribute("role") && "presentation" == c.getAttribute("role") || (a = axs.properties.getTextFromHostLanguageAttributes(c, b, a, e));
   if (e && axs.utils.elementIsHtmlControl(c)) {
-    f = c.ownerDocument.defaultView;
-    if (c instanceof f.HTMLInputElement) {
-      var g = c;
-      "text" == g.type && g.value && 0 < g.value.length && (b.controlValue = {text:g.value});
-      "range" == g.type && (b.controlValue = {text:g.value});
+    d = c.ownerDocument.defaultView;
+    if (c instanceof d.HTMLInputElement) {
+      var f = c;
+      "text" == f.type && f.value && 0 < f.value.length && (b.controlValue = {text:f.value});
+      "range" == f.type && (b.controlValue = {text:f.value});
     }
-    c instanceof f.HTMLSelectElement && (b.controlValue = {text:c.value});
-    b.controlValue && (f = b.controlValue, a ? f.unused = !0 : a = f.text);
+    c instanceof d.HTMLSelectElement && (b.controlValue = {text:c.value});
+    b.controlValue && (d = b.controlValue, a ? d.unused = !0 : a = d.text);
   }
   if (e && axs.utils.elementIsAriaWidget(c)) {
     e = c.getAttribute("role");
@@ -1400,39 +1144,43 @@
       c.hasAttribute("aria-valuetext") ? b.controlValue = {text:c.getAttribute("aria-valuetext")} : c.hasAttribute("aria-valuenow") && (b.controlValue = {value:c.getAttribute("aria-valuenow"), text:"" + c.getAttribute("aria-valuenow")});
     }
     if ("menu" == e) {
-      for (var h = c.querySelectorAll("[role=menuitemcheckbox], [role=menuitemradio]"), f = [], g = 0;g < h.length;g++) {
-        "true" == h[g].getAttribute("aria-checked") && f.push(h[g]);
+      var g = c.querySelectorAll("[role=menuitemcheckbox], [role=menuitemradio]");
+      d = [];
+      for (f = 0;f < g.length;f++) {
+        "true" == g[f].getAttribute("aria-checked") && d.push(g[f]);
       }
-      if (0 < f.length) {
-        h = "";
-        for (g = 0;g < f.length;g++) {
-          h += axs.properties.findTextAlternatives(f[g], {}, !0), g < f.length - 1 && (h += ", ");
+      if (0 < d.length) {
+        g = "";
+        for (f = 0;f < d.length;f++) {
+          g += axs.properties.findTextAlternatives(d[f], {}, !0), f < d.length - 1 && (g += ", ");
         }
-        b.controlValue = {text:h};
+        b.controlValue = {text:g};
       }
     }
     if ("combobox" == e || "select" == e) {
       b.controlValue = {text:"TODO"};
     }
-    b.controlValue && (f = b.controlValue, a ? f.unused = !0 : a = f.text);
+    b.controlValue && (d = b.controlValue, a ? d.unused = !0 : a = d.text);
   }
-  f = !0;
-  c.hasAttribute("role") && (e = c.getAttribute("role"), (e = axs.constants.ARIA_ROLES[e]) && (!e.namefrom || 0 > e.namefrom.indexOf("contents")) && (f = !1));
-  (d = axs.properties.getTextFromDescendantContent(c, d)) && f && (e = {type:"text"}, e.text = d, e.lastWord = axs.properties.getLastWord(e.text), a ? e.unused = !0 : a = d, b.content = e);
-  c.hasAttribute("title") && (d = {type:"string", valid:!0}, d.text = c.getAttribute("title"), d.lastWord = axs.properties.getLastWord(d.lastWord), a ? d.unused = !0 : a = d.text, b.title = d);
+  d = !0;
+  c.hasAttribute("role") && (e = c.getAttribute("role"), (e = axs.constants.ARIA_ROLES[e]) && (!e.namefrom || 0 > e.namefrom.indexOf("contents")) && (d = !1));
+  (e = axs.properties.getTextFromDescendantContent(c)) && d && (d = {type:"text"}, d.text = e, d.lastWord = axs.properties.getLastWord(d.text), a ? d.unused = !0 : a = e, b.content = d);
+  c.hasAttribute("title") && (e = {type:"string", valid:!0}, e.text = c.getAttribute("title"), e.lastWord = axs.properties.getLastWord(e.lastWord), a ? e.unused = !0 : a = e.text, b.title = e);
   return 0 == Object.keys(b).length && null == a ? null : a;
 };
-axs.properties.getTextFromDescendantContent = function(a, b) {
-  for (var c = a.childNodes, d = [], e = 0;e < c.length;e++) {
-    var f = axs.properties.findTextAlternatives(c[e], {}, !0, b);
-    f && d.push(f.trim());
+axs.properties.getTextFromDescendantContent = function(a) {
+  var b = a.childNodes;
+  a = [];
+  for (var c = 0;c < b.length;c++) {
+    var d = axs.properties.findTextAlternatives(b[c], {}, !0);
+    d && a.push(d.trim());
   }
-  if (d.length) {
-    c = "";
-    for (e = 0;e < d.length;e++) {
-      c = [c, d[e]].join(" ").trim();
+  if (a.length) {
+    b = "";
+    for (c = 0;c < a.length;c++) {
+      b = [b, a[c]].join(" ").trim();
     }
-    return c;
+    return b;
   }
   return null;
 };
@@ -1445,18 +1193,22 @@
     var k = {type:"element"}, m = d[h];
     k.value = m;
     var l = document.getElementById(m);
-    l ? (k.valid = !0, k.text = axs.properties.findTextAlternatives(l, {}, !0, !0), k.lastWord = axs.properties.getLastWord(k.text), f.push(k.text), k.element = l) : (k.valid = !1, e.valid = !1, k.errorMessage = {messageKey:"noElementWithId", args:[m]});
+    l ? (k.valid = !0, k.text = axs.properties.findTextAlternatives(l, {}, !0), k.lastWord = axs.properties.getLastWord(k.text), f.push(l.textContent.trim()), k.element = l) : (k.valid = !1, e.valid = !1, k.errorMessage = {messageKey:"noElementWithId", args:[m]});
     g.push(k);
   }
   0 < g.length && (g[g.length - 1].last = !0, e.values = g, e.text = f.join(" "), e.lastWord = axs.properties.getLastWord(e.text), c = e.text, b.ariaLabelledby = e);
   return c;
 };
 axs.properties.getTextFromHostLanguageAttributes = function(a, b, c, d) {
-  if (axs.browserUtils.matchSelector(a, "img") && a.hasAttribute("alt")) {
-    var e = {type:"string", valid:!0};
-    e.text = a.getAttribute("alt");
-    c ? e.unused = !0 : c = e.text;
-    b.alt = e;
+  if (axs.browserUtils.matchSelector(a, "img")) {
+    if (a.hasAttribute("alt")) {
+      var e = {type:"string", valid:!0};
+      e.text = a.getAttribute("alt");
+      c ? e.unused = !0 : c = e.text;
+      b.alt = e;
+    } else {
+      e = {valid:!1, errorMessage:"No alt value provided"}, b.alt = e, e = a.src, "string" == typeof e && (c = e.split("/").pop(), b.filename = {text:c});
+    }
   }
   if (axs.browserUtils.matchSelector(a, 'input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), video:not([disabled])') && !d) {
     if (a.hasAttribute("id")) {
@@ -1469,7 +1221,7 @@
       }
       0 < f.length && (f[f.length - 1].last = !0, e.values = f, e.text = g.join(" "), e.lastWord = axs.properties.getLastWord(e.text), c ? e.unused = !0 : c = e.text, b.labelFor = e);
     }
-    d = axs.dom.parentElement(a);
+    d = axs.utils.parentElement(a);
     for (e = {};d;) {
       if ("label" == d.tagName.toLowerCase() && (f = d, f.control == a)) {
         e.type = "element";
@@ -1478,10 +1230,9 @@
         e.element = f;
         break;
       }
-      d = axs.dom.parentElement(d);
+      d = axs.utils.parentElement(d);
     }
     e.text && (c ? e.unused = !0 : c = e.text, b.labelWrapped = e);
-    axs.browserUtils.matchSelector(a, 'input[type="image"]') && a.hasAttribute("alt") && (e = {type:"string", valid:!0}, e.text = a.getAttribute("alt"), c ? e.unused = !0 : c = e.text, b.alt = e);
     Object.keys(b).length || (b.noLabel = !0);
   }
   return c;
@@ -1494,13 +1245,18 @@
   return a.substring(b > c ? b : c);
 };
 axs.properties.getTextProperties = function(a) {
-  var b = {}, c = axs.properties.findTextAlternatives(a, b, !1, !0);
-  if (0 == Object.keys(b).length && ((a = axs.dom.asElement(a)) && axs.browserUtils.matchSelector(a, "img") && (b.alt = {valid:!1, errorMessage:"No alt value provided"}, a = a.src, "string" == typeof a && (c = a.split("/").pop(), b.filename = {text:c})), !c)) {
-    return null;
+  var b = {};
+  a = axs.properties.findTextAlternatives(a, b, !1, !0);
+  if (0 == Object.keys(b).length) {
+    if (!a) {
+      return null;
+    }
+    b.hasProperties = !1;
+  } else {
+    b.hasProperties = !0;
   }
-  b.hasProperties = Boolean(Object.keys(b).length);
-  b.computedText = c;
-  b.lastWord = axs.properties.getLastWord(c);
+  b.computedText = a;
+  b.lastWord = axs.properties.getLastWord(a);
   return b;
 };
 axs.properties.getAriaProperties = function(a) {
@@ -1533,11 +1289,11 @@
   return 0 < Object.keys(b).length ? b : null;
 };
 axs.properties.getGlobalAriaProperties = function(a) {
-  var b = {}, c;
-  for (c in axs.constants.GLOBAL_PROPERTIES) {
-    if (a.hasAttribute(c)) {
-      var d = a.getAttribute(c);
-      b[c] = axs.utils.getAriaPropertyValue(c, d, a);
+  for (var b = {}, c = 0;c < axs.constants.GLOBAL_PROPERTIES.length;c++) {
+    var d = axs.constants.GLOBAL_PROPERTIES[c];
+    if (a.hasAttribute(d)) {
+      var e = a.getAttribute(d);
+      b[d] = axs.utils.getAriaPropertyValue(d, e, a);
     }
   }
   return b;
@@ -1572,9 +1328,9 @@
   return d;
 };
 axs.properties.getAllProperties = function(a) {
-  var b = axs.dom.asElement(a);
+  var b = axs.utils.asElement(a);
   if (!b) {
-    return {};
+    return{};
   }
   var c = {};
   c.ariaProperties = axs.properties.getAriaProperties(b);
@@ -1584,80 +1340,6 @@
   c.videoProperties = axs.properties.getVideoProperties(b);
   return c;
 };
-(function() {
-  function a(a) {
-    if (!a) {
-      return null;
-    }
-    var c = a.tagName;
-    if (!c) {
-      return null;
-    }
-    c = c.toUpperCase();
-    c = axs.constants.TAG_TO_IMPLICIT_SEMANTIC_INFO[c];
-    if (!c || !c.length) {
-      return null;
-    }
-    for (var d = null, e = 0, f = c.length;e < f;e++) {
-      var g = c[e];
-      if (g.selector) {
-        if (axs.browserUtils.matchSelector(a, g.selector)) {
-          return g;
-        }
-      } else {
-        d = g;
-      }
-    }
-    return d;
-  }
-  axs.properties.getImplicitRole = function(b) {
-    return (b = a(b)) ? b.role : "";
-  };
-  axs.properties.canTakeAriaAttributes = function(b) {
-    return (b = a(b)) ? !b.reserved : !0;
-  };
-})();
-axs.properties.getNativelySupportedAttributes = function(a) {
-  var b = [];
-  if (!a) {
-    return b;
-  }
-  a = a.cloneNode(!1);
-  for (var c = Object.keys(axs.constants.ARIA_TO_HTML_ATTRIBUTE), d = 0;d < c.length;d++) {
-    var e = c[d];
-    axs.constants.ARIA_TO_HTML_ATTRIBUTE[e] in a && (b[b.length] = e);
-  }
-  return b;
-};
-(function() {
-  var a = {};
-  axs.properties.getSelectorForRole = function(b) {
-    if (!b) {
-      return "";
-    }
-    if (a[b] && a.hasOwnProperty(b)) {
-      return a[b];
-    }
-    var c = ['[role="' + b + '"]'];
-    Object.keys(axs.constants.TAG_TO_IMPLICIT_SEMANTIC_INFO).forEach(function(a) {
-      var e = axs.constants.TAG_TO_IMPLICIT_SEMANTIC_INFO[a];
-      if (e && e.length) {
-        for (var f = 0;f < e.length;f++) {
-          var g = e[f];
-          if (g.role === b) {
-            if (g.selector) {
-              c[c.length] = g.selector;
-            } else {
-              c[c.length] = a;
-              break;
-            }
-          }
-        }
-      }
-    });
-    return a[b] = c.join(",");
-  };
-})();
 axs.AuditRule = function(a) {
   for (var b = !0, c = [], d = 0;d < axs.AuditRule.requiredFields.length;d++) {
     var e = axs.AuditRule.requiredFields[d];
@@ -1681,59 +1363,69 @@
   a.push(b);
 };
 axs.AuditRule.collectMatchingElements = function(a, b, c, d) {
-  axs.dom.composedTreeSearch(a, null, {preorder:function(a) {
-    if (d) {
-      for (var f = 0;f < d.length;f++) {
-        if (axs.browserUtils.matchSelector(a, d[f])) {
-          return !1;
-        }
+  if (a.nodeType == Node.ELEMENT_NODE) {
+    var e = a
+  }
+  e && b.call(null, e) && c.push(e);
+  if (e) {
+    var f = e.shadowRoot || e.webkitShadowRoot;
+    if (f) {
+      axs.AuditRule.collectMatchingElements(f, b, c, f);
+      return;
+    }
+  }
+  if (e && "content" == e.localName) {
+    for (e = e.getDistributedNodes(), a = 0;a < e.length;a++) {
+      axs.AuditRule.collectMatchingElements(e[a], b, c, d);
+    }
+  } else {
+    if (e && "shadow" == e.localName) {
+      a = e, d ? (d = d.olderShadowRoot || a.olderShadowRoot) && axs.AuditRule.collectMatchingElements(d, b, c, d) : console.warn("ShadowRoot not provided for", e);
+    } else {
+      for (e = a.firstChild;null != e;) {
+        axs.AuditRule.collectMatchingElements(e, b, c, d), e = e.nextSibling;
       }
     }
-    b(a) && c.push(a);
-    return !0;
-  }});
+  }
 };
 axs.AuditRule.prototype.run = function(a) {
   a = a || {};
-  var b = "maxResults" in a ? a.maxResults : null, c = [];
-  axs.AuditRule.collectMatchingElements("scope" in a ? a.scope : document, this.relevantElementMatcher_, c, a.ignoreSelectors);
-  var d = [];
-  if (!c.length) {
-    return {result:axs.constants.AuditResult.NA};
+  var b = "ignoreSelectors" in a ? a.ignoreSelectors : [], c = "maxResults" in a ? a.maxResults : null, d = [];
+  axs.AuditRule.collectMatchingElements("scope" in a ? a.scope : document, this.relevantElementMatcher_, d);
+  var e = [];
+  if (!d.length) {
+    return{result:axs.constants.AuditResult.NA};
   }
-  for (var e = 0;e < c.length && !(null != b && d.length >= b);e++) {
-    var f = c[e];
-    this.test_(f, a.config) && this.addElement(d, f);
+  for (a = 0;a < d.length && !(null != c && e.length >= c);a++) {
+    var f = d[a], g;
+    a: {
+      g = f;
+      for (var h = 0;h < b.length;h++) {
+        if (axs.browserUtils.matchSelector(g, b[h])) {
+          g = !0;
+          break a;
+        }
+      }
+      g = !1;
+    }
+    !g && this.test_(f) && this.addElement(e, f);
   }
-  a = {result:d.length ? axs.constants.AuditResult.FAIL : axs.constants.AuditResult.PASS, elements:d};
-  e < c.length && (a.resultsTruncated = !0);
-  return a;
+  b = {result:e.length ? axs.constants.AuditResult.FAIL : axs.constants.AuditResult.PASS, elements:e};
+  a < d.length && (b.resultsTruncated = !0);
+  return b;
 };
+axs.AuditRule.specs = {};
 axs.AuditRules = {};
-(function() {
-  var a = {}, b = {};
-  axs.AuditRules.specs = {};
-  axs.AuditRules.addRule = function(c) {
-    var d = new axs.AuditRule(c);
-    if (d.code in b) {
-      throw Error('Can not add audit rule with same code: "' + d.code + '"');
+axs.AuditRules.getRule = function(a) {
+  if (!axs.AuditRules.rules) {
+    axs.AuditRules.rules = {};
+    for (var b in axs.AuditRule.specs) {
+      var c = axs.AuditRule.specs[b], d = new axs.AuditRule(c);
+      axs.AuditRules.rules[c.name] = d;
     }
-    if (d.name in a) {
-      throw Error('Can not add audit rule with same name: "' + d.name + '"');
-    }
-    a[d.name] = b[d.code] = d;
-    axs.AuditRules.specs[c.name] = c;
-  };
-  axs.AuditRules.getRule = function(c) {
-    return a[c] || b[c] || null;
-  };
-  axs.AuditRules.getRules = function(b) {
-    var d = Object.keys(a);
-    return b ? d : d.map(function(a) {
-      return this.getRule(a);
-    }, axs.AuditRules);
-  };
-})();
+  }
+  return axs.AuditRules.rules[a];
+};
 axs.AuditResults = function() {
   this.errors_ = [];
   this.warnings_ = [];
@@ -1775,15 +1467,11 @@
 };
 goog.exportProperty(axs.AuditResults.prototype, "toString", axs.AuditResults.prototype.toString);
 axs.Audit = {};
-axs.AuditConfiguration = function(a) {
-  null == a && (a = {});
+axs.AuditConfiguration = function() {
   this.rules_ = {};
   this.maxResults = this.auditRulesToIgnore = this.auditRulesToRun = this.scope = null;
   this.withConsoleApi = !1;
   this.showUnsupportedRulesWarning = !0;
-  for (var b in this) {
-    this.hasOwnProperty(b) && b in a && (this[b] = a[b]);
-  }
   goog.exportProperty(this, "scope", this.scope);
   goog.exportProperty(this, "auditRulesToRun", this.auditRulesToRun);
   goog.exportProperty(this, "auditRulesToIgnore", this.auditRulesToIgnore);
@@ -1802,26 +1490,21 @@
   this.rules_[a].severity = b;
 }, getSeverity:function(a) {
   return a in this.rules_ && "severity" in this.rules_[a] ? this.rules_[a].severity : null;
-}, setRuleConfig:function(a, b) {
-  a in this.rules_ || (this.rules_[a] = {});
-  this.rules_[a].config = b;
-}, getRuleConfig:function(a) {
-  return a in this.rules_ && "config" in this.rules_[a] ? this.rules_[a].config : null;
 }};
 goog.exportProperty(axs.AuditConfiguration.prototype, "ignoreSelectors", axs.AuditConfiguration.prototype.ignoreSelectors);
 goog.exportProperty(axs.AuditConfiguration.prototype, "getIgnoreSelectors", axs.AuditConfiguration.prototype.getIgnoreSelectors);
 axs.Audit.unsupportedRulesWarningShown = !1;
 axs.Audit.getRulesCannotRun = function(a) {
-  return a.withConsoleApi ? [] : axs.AuditRules.getRules().filter(function(a) {
-    return a.requiresConsoleAPI;
+  return a.withConsoleApi ? [] : Object.keys(axs.AuditRule.specs).filter(function(a) {
+    return axs.AuditRules.getRule(a).requiresConsoleAPI;
   }).map(function(a) {
-    return a.code;
+    return axs.AuditRules.getRule(a).code;
   });
 };
 axs.Audit.run = function(a) {
   a = a || new axs.AuditConfiguration;
   var b = a.withConsoleApi, c = [], d;
-  d = a.auditRulesToRun && 0 < a.auditRulesToRun.length ? a.auditRulesToRun : axs.AuditRules.getRules(!0);
+  d = a.auditRulesToRun && 0 < a.auditRulesToRun.length ? a.auditRulesToRun : Object.keys(axs.AuditRule.specs);
   if (a.auditRulesToIgnore) {
     for (var e = 0;e < a.auditRulesToIgnore.length;e++) {
       var f = a.auditRulesToIgnore[e];
@@ -1836,8 +1519,6 @@
       if (0 < k.length || a.scope) {
         h.ignoreSelectors = k;
       }
-      k = a.getRuleConfig(g.name);
-      null != k && (h.config = k);
       a.scope && (h.scope = a.scope);
       a.maxResults && (h.maxResults = a.maxResults);
       h = g.run.call(g, h);
@@ -1878,72 +1559,17 @@
   return b;
 };
 goog.exportSymbol("axs.Audit.accessibilityErrorMessage", axs.Audit.accessibilityErrorMessage);
-axs.AuditRules.addRule({name:"ariaOnReservedElement", heading:"This element does not support ARIA roles, states and properties", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_12", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
-  return !axs.properties.canTakeAriaAttributes(a);
-}, test:function(a) {
-  return null !== axs.properties.getAriaProperties(a);
-}, code:"AX_ARIA_12"});
-axs.AuditRules.addRule({name:"ariaOwnsDescendant", heading:"aria-owns should not be used if ownership is implicit in the DOM", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_06", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
-  return axs.browserUtils.matchSelector(a, "[aria-owns]");
-}, test:function(a) {
-  return axs.utils.getIdReferents("aria-owns", a).some(function(b) {
-    return a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_CONTAINED_BY;
-  });
-}, code:"AX_ARIA_06"});
-axs.AuditRules.addRule({name:"ariaRoleNotScoped", heading:"Elements with ARIA roles must be in the correct scope", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_09", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
-  return axs.browserUtils.matchSelector(a, "[role]");
-}, test:function(a) {
-  var b = axs.utils.getRoles(a);
-  if (!b || !b.applied) {
-    return !1;
-  }
-  b = b.applied.details.scope;
-  if (!b || 0 === b.length) {
-    return !1;
-  }
-  for (var c = a;c = axs.dom.parentElement(c);) {
-    var d = axs.utils.getRoles(c, !0);
-    if (d && d.applied && 0 <= b.indexOf(d.applied.name)) {
-      return !1;
-    }
-  }
-  if (a = axs.utils.getAriaIdReferrers(a, "aria-owns")) {
-    for (c = 0;c < a.length;c++) {
-      if ((d = axs.utils.getRoles(a[c], !0)) && d.applied && 0 <= b.indexOf(d.applied.name)) {
-        return !1;
-      }
-    }
-  }
-  return !0;
-}, code:"AX_ARIA_09"});
-axs.AuditRules.addRule({name:"audioWithoutControls", heading:"Audio elements should have controls", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_audio_01", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
+axs.AuditRule.specs.audioWithoutControls = {name:"audioWithoutControls", heading:"Audio elements should have controls", url:"", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
   return axs.browserUtils.matchSelector(a, "audio[autoplay]");
 }, test:function(a) {
-  return !a.querySelectorAll("[controls]").length && 3 < a.duration;
-}, code:"AX_AUDIO_01"});
-(function() {
-  var a = /^aria\-/;
-  axs.AuditRules.addRule({name:"badAriaAttribute", heading:"This element has an invalid ARIA attribute", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_11", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(b) {
-    b = b.attributes;
-    for (var c = 0, d = b.length;c < d;c++) {
-      if (a.test(b[c].name)) {
-        return !0;
-      }
-    }
-    return !1;
-  }, test:function(b) {
-    b = b.attributes;
-    for (var c = 0, d = b.length;c < d;c++) {
-      var e = b[c].name;
-      if (a.test(e) && (e = e.replace(a, ""), !axs.constants.ARIA_PROPERTIES.hasOwnProperty(e))) {
-        return !0;
-      }
-    }
-    return !1;
-  }, code:"AX_ARIA_11"});
-})();
-axs.AuditRules.addRule({name:"badAriaAttributeValue", heading:"ARIA state and property values must be valid", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_04", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
-  var b = axs.utils.getSelectorForAriaProperties(axs.constants.ARIA_PROPERTIES);
+  return!a.querySelectorAll("[controls]").length && 3 < a.duration;
+}, code:"AX_AUDIO_01"};
+axs.AuditRule.specs.badAriaAttributeValue = {name:"badAriaAttributeValue", heading:"ARIA state and property values must be valid", url:"", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
+  var b = "", c;
+  for (c in axs.constants.ARIA_PROPERTIES) {
+    b += "[aria-" + c + "],";
+  }
+  b = b.substring(0, b.length - 1);
   return axs.browserUtils.matchSelector(a, b);
 }, test:function(a) {
   for (var b in axs.constants.ARIA_PROPERTIES) {
@@ -1951,328 +1577,135 @@
     if (a.hasAttribute(c)) {
       var d = a.getAttribute(c);
       if (!axs.utils.getAriaPropertyValue(c, d, a).valid) {
-        return !0;
+        return!0;
       }
     }
   }
-  return !1;
-}, code:"AX_ARIA_04"});
-axs.AuditRules.addRule({name:"badAriaRole", heading:"Elements with ARIA roles must use a valid, non-abstract ARIA role", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_01", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
+  return!1;
+}, code:"AX_ARIA_04"};
+axs.AuditRule.specs.badAriaRole = {name:"badAriaRole", heading:"Elements with ARIA roles must use a valid, non-abstract ARIA role", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_aria_01--elements-with-aria-roles-must-use-a-valid-non-abstract-aria-role", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
   return axs.browserUtils.matchSelector(a, "[role]");
 }, test:function(a) {
-  return !axs.utils.getRoles(a).valid;
-}, code:"AX_ARIA_01"});
-axs.AuditRules.addRule({name:"controlsWithoutLabel", heading:"Controls and media elements should have labels", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_text_01", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
-  if (!axs.browserUtils.matchSelector(a, 'input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), video:not([disabled])') || "presentation" == a.getAttribute("role")) {
-    return !1;
+  return!axs.utils.getRoles(a).valid;
+}, code:"AX_ARIA_01"};
+axs.AuditRule.specs.controlsWithoutLabel = {name:"controlsWithoutLabel", heading:"Controls and media elements should have labels", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_text_01--controls-and-media-elements-should-have-labels", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
+  if (!axs.browserUtils.matchSelector(a, 'input:not([type="hidden"]):not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), video:not([disabled])')) {
+    return!1;
   }
   if (0 <= a.tabIndex) {
-    return !0;
+    return!0;
   }
-  for (a = axs.dom.parentElement(a);null != a;a = axs.dom.parentElement(a)) {
+  for (a = axs.utils.parentElement(a);null != a;a = axs.utils.parentElement(a)) {
     if (axs.utils.elementIsAriaWidget(a)) {
-      return !1;
+      return!1;
     }
   }
-  return !0;
+  return!0;
 }, test:function(a) {
-  if (axs.utils.isElementOrAncestorHidden(a) || "input" == a.tagName.toLowerCase() && "button" == a.type && a.value.length || "button" == a.tagName.toLowerCase() && a.textContent.replace(/^\s+|\s+$/g, "").length || axs.utils.hasLabel(a)) {
-    return !1;
-  }
-  a = axs.properties.findTextAlternatives(a, {});
-  return null === a || "" === a.trim() ? !0 : !1;
-}, code:"AX_TEXT_01", ruleName:"Controls and media elements should have labels"});
-axs.AuditRules.addRule({name:"duplicateId", heading:"Any ID referred to via an IDREF must be unique in the DOM", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_html_02", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
-  return a.hasAttribute("id") ? axs.utils.getIdReferrers(a).some(function(a) {
-    return !axs.utils.isElementOrAncestorHidden(a);
-  }) : !1;
-}, test:function(a) {
-  var b = "[id='" + a.id.replace(/'/g, "\\'") + "']";
-  return 1 < a.ownerDocument.querySelectorAll(b).length;
-}, code:"AX_HTML_02"});
-axs.AuditRules.addRule({name:"focusableElementNotVisibleAndNotAriaHidden", heading:"These elements are focusable but either invisible or obscured by another element", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_01", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
+  return axs.utils.isElementOrAncestorHidden(a) || "input" == a.tagName.toLowerCase() && "button" == a.type && a.value.length || "button" == a.tagName.toLowerCase() && a.textContent.replace(/^\s+|\s+$/g, "").length ? !1 : axs.utils.hasLabel(a) ? !1 : !0;
+}, code:"AX_TEXT_01", ruleName:"Controls and media elements should have labels"};
+axs.AuditRule.specs.focusableElementNotVisibleAndNotAriaHidden = {name:"focusableElementNotVisibleAndNotAriaHidden", heading:"These elements are focusable but either invisible or obscured by another element", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_focus_01--these-elements-are-focusable-but-either-invisible-or-obscured-by-another-element", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
   if (!axs.browserUtils.matchSelector(a, axs.utils.FOCUSABLE_ELEMENTS_SELECTOR)) {
-    return !1;
+    return!1;
   }
   if (0 <= a.tabIndex) {
-    return !0;
+    return!0;
   }
-  for (var b = axs.dom.parentElement(a);null != b;b = axs.dom.parentElement(b)) {
-    if (axs.utils.elementIsAriaWidget(b)) {
-      return !1;
+  for (a = axs.utils.parentElement(a);null != a;a = axs.utils.parentElement(a)) {
+    if (axs.utils.elementIsAriaWidget(a)) {
+      return!1;
     }
   }
-  a = axs.properties.findTextAlternatives(a, {});
-  return null === a || "" === a.trim() ? !1 : !0;
+  return!0;
 }, test:function(a) {
   if (axs.utils.isElementOrAncestorHidden(a)) {
-    return !1;
+    return!1;
   }
   a.focus();
-  return !axs.utils.elementIsVisible(a);
-}, code:"AX_FOCUS_01"});
-axs.AuditRules.addRule({name:"humanLangMissing", heading:"The web page should have the content's human language indicated in the markup", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_html_01", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
-  return a instanceof a.ownerDocument.defaultView.HTMLHtmlElement;
-}, test:function(a) {
-  return a.lang ? !1 : !0;
-}, code:"AX_HTML_01"});
-axs.AuditRules.addRule({name:"imagesWithoutAltText", heading:"Images should have a text alternative or presentational role", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_text_02", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
+  return!axs.utils.elementIsVisible(a);
+}, code:"AX_FOCUS_01"};
+axs.AuditRule.specs.imagesWithoutAltText = {name:"imagesWithoutAltText", heading:"Images should have an alt attribute", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_text_02--images-should-have-an-alt-attribute-unless-they-have-an-aria-role-of-presentation", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
   return axs.browserUtils.matchSelector(a, "img") && !axs.utils.isElementOrAncestorHidden(a);
 }, test:function(a) {
-  if (a.hasAttribute("alt") && "" == a.alt || "presentation" == a.getAttribute("role")) {
-    return !1;
-  }
-  var b = {};
-  axs.properties.findTextAlternatives(a, b);
-  return 0 == Object.keys(b).length ? !0 : !1;
-}, code:"AX_TEXT_02"});
-axs.AuditRules.addRule({name:"linkWithUnclearPurpose", heading:"The purpose of each link should be clear from the link text", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_text_04", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
-  return axs.browserUtils.matchSelector(a, "a[href]") && !axs.utils.isElementOrAncestorHidden(a);
-}, test:function(a, b) {
-  for (var c = b || {}, d = c.blacklistPhrases || [], e = /\s+/, f = 0;f < d.length;f++) {
-    var g = "^\\s*" + d[f].trim().replace(e, "\\s*") + "s*[^a-z]$";
-    if ((new RegExp(g, "i")).test(a.textContent)) {
-      return !0;
-    }
-  }
-  c = c.stopwords || "click tap go here learn more this page link about".split(" ");
-  d = axs.properties.findTextAlternatives(a, {});
-  if (null === d || "" === d.trim()) {
-    return !0;
-  }
-  d = d.replace(/[^a-zA-Z ]/g, "");
-  for (f = 0;f < c.length;f++) {
-    if (d = d.replace(new RegExp("\\b" + c[f] + "\\b", "ig"), ""), "" == d.trim()) {
-      return !0;
-    }
-  }
-  return !1;
-}, code:"AX_TEXT_04"});
-axs.AuditRules.addRule({name:"lowContrastElements", heading:"Text elements should have a reasonable contrast ratio", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_color_01", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
-  return axs.properties.hasDirectTextDescendant(a) && !axs.utils.isElementDisabled(a);
+  return!a.hasAttribute("alt") && "presentation" != a.getAttribute("role");
+}, code:"AX_TEXT_02"};
+axs.AuditRule.specs.linkWithUnclearPurpose = {name:"linkWithUnclearPurpose", heading:"The purpose of each link should be clear from the link text", url:"", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
+  return axs.browserUtils.matchSelector(a, "a");
+}, test:function(a) {
+  return/^\s*click\s*here\s*[^a-z]?$/i.test(a.textContent);
+}, code:"AX_TITLE_01"};
+axs.AuditRule.specs.lowContrastElements = {name:"lowContrastElements", heading:"Text elements should have a reasonable contrast ratio", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_color_01--text-elements-should-have-a-reasonable-contrast-ratio", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
+  return axs.properties.hasDirectTextDescendant(a);
 }, test:function(a) {
   var b = window.getComputedStyle(a, null);
-  return (a = axs.utils.getContrastRatioForElementWithComputedStyle(b, a)) && axs.utils.isLowContrast(a, b);
-}, code:"AX_COLOR_01"});
-axs.AuditRules.addRule({name:"mainRoleOnInappropriateElement", heading:"role=main should only appear on significant elements", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_05", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
+  return(a = axs.utils.getContrastRatioForElementWithComputedStyle(b, a)) && axs.utils.isLowContrast(a, b);
+}, code:"AX_COLOR_01"};
+axs.AuditRule.specs.mainRoleOnInappropriateElement = {name:"mainRoleOnInappropriateElement", heading:"role=main should only appear on significant elements", url:"", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
   return axs.browserUtils.matchSelector(a, "[role~=main]");
 }, test:function(a) {
   if (axs.utils.isInlineElement(a)) {
-    return !0;
+    return!0;
   }
   a = axs.properties.getTextFromDescendantContent(a);
-  return !a || 50 > a.length ? !0 : !1;
-}, code:"AX_ARIA_05"});
-axs.AuditRules.addRule({name:"elementsWithMeaningfulBackgroundImage", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
-  return !axs.utils.isElementOrAncestorHidden(a);
-}, heading:"Meaningful images should not be used in element backgrounds", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_image_01", test:function(a) {
+  return!a || 50 > a.length ? !0 : !1;
+}, code:"AX_ARIA_04"};
+axs.AuditRule.specs.elementsWithMeaningfulBackgroundImage = {name:"elementsWithMeaningfulBackgroundImage", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
+  return!axs.utils.isElementOrAncestorHidden(a);
+}, heading:"Meaningful images should not be used in element backgrounds", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_image_01--meaningful-images-should-not-be-used-in-element-backgrounds", test:function(a) {
   if (a.textContent && 0 < a.textContent.length) {
-    return !1;
+    return!1;
   }
   a = window.getComputedStyle(a, null);
   var b = a.backgroundImage;
   if (!b || "undefined" === b || "none" === b || 0 != b.indexOf("url")) {
-    return !1;
+    return!1;
   }
   b = parseInt(a.width, 10);
   a = parseInt(a.height, 10);
   return 150 > b && 150 > a;
-}, code:"AX_IMAGE_01"});
-axs.AuditRules.addRule({name:"multipleAriaOwners", heading:"An element's ID must not be present in more that one aria-owns attribute at any time", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_07", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
-  return axs.browserUtils.matchSelector(a, "[aria-owns]");
+}, code:"AX_IMAGE_01"};
+axs.AuditRule.specs.nonExistentAriaLabelledbyElement = {name:"nonExistentAriaLabelledbyElement", heading:"aria-labelledby attributes should refer to an element which exists in the DOM", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_aria_02--aria-labelledby-attributes-should-refer-to-an-element-which-exists-in-the-dom", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
+  return axs.browserUtils.matchSelector(a, "[aria-labelledby]");
 }, test:function(a) {
-  return axs.utils.getIdReferents("aria-owns", a).some(function(a) {
-    return 1 < axs.utils.getAriaIdReferrers(a, "aria-owns").length;
-  });
-}, code:"AX_ARIA_07"});
-axs.AuditRules.addRule({name:"multipleLabelableElementsPerLabel", heading:"A label element may not have labelable descendants other than its labeled control.", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_text_03--labels-should-only-contain-one-labelable-element", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
-  return axs.browserUtils.matchSelector(a, "label");
-}, test:function(a) {
-  if (1 < a.querySelectorAll(axs.utils.LABELABLE_ELEMENTS_SELECTOR).length) {
-    return !0;
-  }
-}, code:"AX_TEXT_03"});
-axs.AuditRules.addRule({name:"nonExistentAriaRelatedElement", heading:"ARIA attributes which refer to other elements by ID should refer to elements which exist in the DOM", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_02", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
-  var b = axs.utils.getAriaPropertiesByValueType(["idref", "idref_list"]), b = axs.utils.getSelectorForAriaProperties(b);
-  return axs.browserUtils.matchSelector(a, b);
-}, test:function(a) {
-  for (var b = axs.utils.getAriaPropertiesByValueType(["idref", "idref_list"]), b = axs.utils.getSelectorForAriaProperties(b).split(","), c = 0, d = b.length;c < d;c++) {
-    var e = b[c];
-    if (axs.browserUtils.matchSelector(a, e)) {
-      var e = e.match(/aria-[^\]]+/)[0], f = a.getAttribute(e);
-      if (!axs.utils.getAriaPropertyValue(e, f, a).valid) {
-        return !0;
-      }
+  a = a.getAttribute("aria-labelledby").split(/\s+/);
+  for (var b = 0;b < a.length;b++) {
+    if (!document.getElementById(a[b])) {
+      return!0;
     }
   }
-  return !1;
-}, code:"AX_ARIA_02"});
-axs.AuditRules.addRule({name:"pageWithoutTitle", heading:"The web page should have a title that describes topic or purpose", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_title_01", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
+  return!1;
+}, code:"AX_ARIA_02"};
+axs.AuditRule.specs.pageWithoutTitle = {name:"pageWithoutTitle", heading:"The web page should have a title that describes topic or purpose", url:"", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
   return "html" == a.tagName.toLowerCase();
 }, test:function(a) {
   a = a.querySelector("head");
   return a ? (a = a.querySelector("title")) ? !a.textContent : !0 : !0;
-}, code:"AX_TITLE_01"});
-axs.AuditRules.addRule({name:"requiredAriaAttributeMissing", heading:"Elements with ARIA roles must have all required attributes for that role", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_03", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
+}, code:"AX_TITLE_01"};
+axs.AuditRule.specs.requiredAriaAttributeMissing = {name:"requiredAriaAttributeMissing", heading:"Elements with ARIA roles must have all required attributes for that role", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_aria_03--elements-with-aria-roles-must-have-all-required-attributes-for-that-role", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
   return axs.browserUtils.matchSelector(a, "[role]");
 }, test:function(a) {
   var b = axs.utils.getRoles(a);
   if (!b.valid) {
-    return !1;
+    return!1;
   }
   for (var c = 0;c < b.roles.length;c++) {
     var d = b.roles[c].details.requiredPropertiesSet, e;
     for (e in d) {
-      if (d = e.replace(/^aria-/, ""), !("defaultValue" in axs.constants.ARIA_PROPERTIES[d] || a.hasAttribute(e)) && 0 > axs.properties.getNativelySupportedAttributes(a).indexOf(e)) {
-        return !0;
+      if (d = e.replace(/^aria-/, ""), !("defaultValue" in axs.constants.ARIA_PROPERTIES[d] || a.hasAttribute(e))) {
+        return!0;
       }
     }
   }
-}, code:"AX_ARIA_03"});
-(function() {
-  function a(a) {
-    a = axs.utils.getRoles(a);
-    if (!a || !a.applied) {
-      return [];
-    }
-    a = a.applied;
-    return a.valid ? a.details.mustcontain || [] : [];
-  }
-  axs.AuditRules.addRule({name:"requiredOwnedAriaRoleMissing", heading:"Elements with ARIA roles must ensure required owned elements are present", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_08", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(b) {
-    return axs.browserUtils.matchSelector(b, "[role]") ? 0 < a(b).length : !1;
-  }, test:function(b) {
-    if ("true" === b.getAttribute("aria-busy")) {
-      return !1;
-    }
-    for (var c = a(b), d = c.length - 1;0 <= d;d--) {
-      var e = axs.utils.findDescendantsWithRole(b, c[d]);
-      if (e && e.length) {
-        return !1;
-      }
-    }
-    b = axs.utils.getIdReferents("aria-owns", b);
-    for (d = b.length - 1;0 <= d;d--) {
-      if ((e = axs.utils.getRoles(b[d], !0)) && e.applied) {
-        for (var e = e.applied, f = c.length - 1;0 <= f;f--) {
-          if (e.name === c[f]) {
-            return !1;
-          }
-        }
-      }
-    }
-    return !0;
-  }, code:"AX_ARIA_08"});
-})();
-axs.AuditRules.addRule({name:"roleTooltipRequiresDescribedby", heading:"Elements with role=tooltip should have a corresponding element with aria-describedby", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_02", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
-  return axs.browserUtils.matchSelector(a, "[role=tooltip]") && !axs.utils.isElementOrAncestorHidden(a);
-}, test:function(a) {
-  return 0 === axs.utils.getAriaIdReferrers(a, "aria-describedby").length;
-}, code:"AX_TOOLTIP_01"});
-axs.AuditRules.addRule({name:"tabIndexGreaterThanZero", heading:"Avoid positive integer values for tabIndex", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_03", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
-  return axs.browserUtils.matchSelector(a, "[tabindex]");
-}, test:function(a) {
-  if (0 < a.tabIndex) {
-    return !0;
-  }
-}, code:"AX_FOCUS_03"});
-(function() {
-  axs.AuditRules.addRule({name:"tableHasAppropriateHeaders", heading:"Tables should have appropriate headers", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_table_01", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
-    return axs.browserUtils.matchSelector(a, "table");
-  }, test:function(a) {
-    if ("presentation" == a.getAttribute("role")) {
-      return 0 != a.querySelectorAll("th").length;
-    }
-    a = a.querySelectorAll("tr");
-    var b;
-    a: {
-      b = a[0].children;
-      for (var c = 0;c < b.length;c++) {
-        if ("TH" != b[c].tagName) {
-          b = !0;
-          break a;
-        }
-      }
-      b = !1;
-    }
-    if (b) {
-      a: {
-        for (b = 0;b < a.length;b++) {
-          if ("TH" != a[b].children[0].tagName) {
-            b = !0;
-            break a;
-          }
-        }
-        b = !1;
-      }
-    }
-    if (b) {
-      a: {
-        b = a[0].children;
-        for (c = 1;c < b.length;c++) {
-          if ("TH" != b[c].tagName) {
-            b = !0;
-            break a;
-          }
-        }
-        for (c = 1;c < a.length;c++) {
-          if ("TH" != a[c].children[0].tagName) {
-            b = !0;
-            break a;
-          }
-        }
-        b = !1;
-      }
-    }
-    return b;
-  }, code:"AX_TABLE_01"});
-})();
-(function() {
-  axs.AuditRules.addRule({name:"uncontrolledTabpanel", heading:"A tabpanel should be related to a tab via aria-controls or aria-labelledby", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_13", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
-    return axs.browserUtils.matchSelector(a, '[role="tabpanel"]');
-  }, test:function(a) {
-    var b;
-    b = document.querySelectorAll('[role="tab"][aria-controls="' + a.id + '"]');
-    (b = a.id && 1 === b.length) || (a.hasAttribute("aria-labelledby") ? (a = document.querySelectorAll("#" + a.getAttribute("aria-labelledby")), b = 1 === a.length && "tab" === a[0].getAttribute("role")) : b = !1);
-    return !b;
-  }, code:"AX_ARIA_13"});
-})();
-axs.AuditRules.addRule({name:"unfocusableElementsWithOnClick", heading:"Elements with onclick handlers must be focusable", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_focus_02", severity:axs.constants.Severity.WARNING, opt_requiresConsoleAPI:!0, relevantElementMatcher:function(a) {
+}, code:"AX_ARIA_03"};
+axs.AuditRule.specs.unfocusableElementsWithOnClick = {name:"unfocusableElementsWithOnClick", heading:"Elements with onclick handlers must be focusable", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_focus_02--elements-with-onclick-handlers-must-be-focusable", severity:axs.constants.Severity.WARNING, opt_requiresConsoleAPI:!0, relevantElementMatcher:function(a) {
   return a instanceof a.ownerDocument.defaultView.HTMLBodyElement || axs.utils.isElementOrAncestorHidden(a) ? !1 : "click" in getEventListeners(a) ? !0 : !1;
 }, test:function(a) {
-  return !a.hasAttribute("tabindex") && !axs.utils.isElementImplicitlyFocusable(a) && !a.disabled;
-}, code:"AX_FOCUS_02"});
-(function() {
-  var a = /^aria\-/, b = axs.utils.getSelectorForAriaProperties(axs.constants.ARIA_PROPERTIES);
-  axs.AuditRules.addRule({name:"unsupportedAriaAttribute", heading:"This element has an unsupported ARIA attribute", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_10", severity:axs.constants.Severity.SEVERE, relevantElementMatcher:function(a) {
-    return axs.browserUtils.matchSelector(a, b);
-  }, test:function(b) {
-    var d = axs.utils.getRoles(b, !0), d = d && d.applied ? d.applied.details.propertiesSet : axs.constants.GLOBAL_PROPERTIES;
-    b = b.attributes;
-    for (var e = 0, f = b.length;e < f;e++) {
-      var g = b[e].name;
-      if (a.test(g)) {
-        var h = g.replace(a, "");
-        if (axs.constants.ARIA_PROPERTIES.hasOwnProperty(h) && !(g in d)) {
-          return !0;
-        }
-      }
-    }
-    return !1;
-  }, code:"AX_ARIA_10"});
-})();
-axs.AuditRules.addRule({name:"videoWithoutCaptions", heading:"Video elements should use <track> elements to provide captions", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_video_01", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
+  return!a.hasAttribute("tabindex") && !axs.utils.isElementImplicitlyFocusable(a) && !a.disabled;
+}, code:"AX_FOCUS_02"};
+axs.AuditRule.specs.videoWithoutCaptions = {name:"videoWithoutCaptions", heading:"Video elements should use <track> elements to provide captions", url:"https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_video_01--video-elements-should-use-track-elements-to-provide-captions", severity:axs.constants.Severity.WARNING, relevantElementMatcher:function(a) {
   return axs.browserUtils.matchSelector(a, "video");
 }, test:function(a) {
-  return !a.querySelectorAll("track[kind=captions]").length;
-}, code:"AX_VIDEO_01"});
+  return!a.querySelectorAll("track[kind=captions]").length;
+}, code:"AX_VIDEO_01"};
 
-  return axs;
-});
-
-// Define AMD module if possible, export globals otherwise.
-if (typeof define !== 'undefined' && define.amd) {
-  define([], fn);
-} else {
-  var axs = fn.call(this);
-}
 
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium
index a71396a..b80685a 100644
--- a/third_party/libjingle/README.chromium
+++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@
 Name: libjingle
 URL: http://www.webrtc.org
 Version: unknown
-Revision: 10776
+Revision: 10790
 License: BSD
 License File: source/talk/COPYING
 Security Critical: yes
diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c
index 80d4c22..ac1bb392 100644
--- a/third_party/sqlite/amalgamation/sqlite3.c
+++ b/third_party/sqlite/amalgamation/sqlite3.c
@@ -7575,11 +7575,6 @@
                                                const char* fileName,
                                                int noLock);
 CHROMIUM_SQLITE_API
-int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file,
-                                              const char* fileName,
-                                              int flags,
-                                              int* fd);
-CHROMIUM_SQLITE_API
 void chromium_sqlite3_update_reusable_file_handle(sqlite3_file* file,
                                                   int fd,
                                                   int flags);
@@ -30513,36 +30508,6 @@
 }
 
 /*
-** Search for an unused file descriptor that was opened on the database file.
-** If a suitable file descriptor if found, then it is stored in *fd; otherwise,
-** *fd is not modified.
-**
-** If a reusable file descriptor is not found, and a new UnixUnusedFd cannot
-** be allocated, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK is returned.
-*/
-CHROMIUM_SQLITE_API
-int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file,
-                                              const char* fileName,
-                                              int flags,
-                                              int* fd) {
-  unixFile* unixSQLite3File = (unixFile*)file;
-  int fileType = flags & 0xFFFFFF00;
-  if (fileType == SQLITE_OPEN_MAIN_DB) {
-    UnixUnusedFd *unusedFd = findReusableFd(fileName, flags);
-    if (unusedFd) {
-      *fd = unusedFd->fd;
-    } else {
-      unusedFd = sqlite3_malloc(sizeof(*unusedFd));
-      if (!unusedFd) {
-        return SQLITE_NOMEM;
-      }
-    }
-    unixSQLite3File->pUnused = unusedFd;
-  }
-  return SQLITE_OK;
-}
-
-/*
 ** Marks 'fd' as the unused file descriptor for 'pFile'.
 */
 CHROMIUM_SQLITE_API
@@ -30669,10 +30634,17 @@
   chromium_sqlite3_initialize_unix_sqlite3_file(pFile);
 
   if( eType==SQLITE_OPEN_MAIN_DB ){
-    rc = chromium_sqlite3_get_reusable_file_handle(pFile, zName, flags, &fd);
-    if( rc!=SQLITE_OK ){
-      return rc;
+    UnixUnusedFd *pUnused;
+    pUnused = findReusableFd(zName, flags);
+    if( pUnused ){
+      fd = pUnused->fd;
+    }else{
+      pUnused = sqlite3_malloc(sizeof(*pUnused));
+      if( !pUnused ){
+        return SQLITE_NOMEM;
+      }
     }
+    p->pUnused = pUnused;
 
     /* Database filenames are double-zero terminated if they are not
     ** URIs with parameters.  Hence, they can always be passed into
diff --git a/third_party/sqlite/amalgamation/sqlite3.h b/third_party/sqlite/amalgamation/sqlite3.h
index dfa538e..2713c32 100644
--- a/third_party/sqlite/amalgamation/sqlite3.h
+++ b/third_party/sqlite/amalgamation/sqlite3.h
@@ -7451,11 +7451,6 @@
                                                const char* fileName,
                                                int noLock);
 CHROMIUM_SQLITE_API
-int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file,
-                                              const char* fileName,
-                                              int flags,
-                                              int* fd);
-CHROMIUM_SQLITE_API
 void chromium_sqlite3_update_reusable_file_handle(sqlite3_file* file,
                                                   int fd,
                                                   int flags);
diff --git a/third_party/sqlite/patches/0005-Modify-default-VFS-to-support-WebDatabase.patch b/third_party/sqlite/patches/0005-Modify-default-VFS-to-support-WebDatabase.patch
index 81343dad..6cff9b3 100644
--- a/third_party/sqlite/patches/0005-Modify-default-VFS-to-support-WebDatabase.patch
+++ b/third_party/sqlite/patches/0005-Modify-default-VFS-to-support-WebDatabase.patch
@@ -1,7 +1,7 @@
-From 4b957c2c198a53498fe18ad9668e2817ace98b1e Mon Sep 17 00:00:00 2001
+From e646ccd23c9eaa86e4e6b0f5ee60867010407346 Mon Sep 17 00:00:00 2001
 From: dumi <dumi@chromium.org>
 Date: Mon, 20 Jul 2009 23:40:51 +0000
-Subject: [PATCH 05/11] Modify default VFS to support WebDatabase.
+Subject: [PATCH 05/12] Modify default VFS to support WebDatabase.
 
 The renderer WebDatabase implementation needs to broker certain requests
 to the browser.  This modifies SQLite to allow monkey-patching the VFS
@@ -17,13 +17,13 @@
 https://codereview.chromium.org/377039
 [Possibly not a complete list.]
 ---
- third_party/sqlite/src/src/os_unix.c   | 100 +++++++++++++++++++++++++++------
- third_party/sqlite/src/src/os_win.c    |   8 +++
- third_party/sqlite/src/src/sqlite.h.in |  36 ++++++++++++
- 3 files changed, 128 insertions(+), 16 deletions(-)
+ third_party/sqlite/src/src/os_unix.c   | 57 ++++++++++++++++++++++++++++++----
+ third_party/sqlite/src/src/os_win.c    |  8 +++++
+ third_party/sqlite/src/src/sqlite.h.in | 31 ++++++++++++++++++
+ 3 files changed, 90 insertions(+), 6 deletions(-)
 
 diff --git a/third_party/sqlite/src/src/os_unix.c b/third_party/sqlite/src/src/os_unix.c
-index a9344ee..75b71dc 100644
+index a9344ee..c6e1b6c 100644
 --- a/third_party/sqlite/src/src/os_unix.c
 +++ b/third_party/sqlite/src/src/os_unix.c
 @@ -1321,6 +1321,12 @@ static int fileHasMoved(unixFile *pFile){
@@ -39,7 +39,7 @@
    return pFile->pInode!=0 &&
        (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino);
  #endif
-@@ -5615,6 +5621,78 @@ static int findCreateFileMode(
+@@ -5615,6 +5621,48 @@ static int findCreateFileMode(
  }
  
  /*
@@ -62,36 +62,6 @@
 +}
 +
 +/*
-+** Search for an unused file descriptor that was opened on the database file.
-+** If a suitable file descriptor if found, then it is stored in *fd; otherwise,
-+** *fd is not modified.
-+**
-+** If a reusable file descriptor is not found, and a new UnixUnusedFd cannot
-+** be allocated, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK is returned.
-+*/
-+CHROMIUM_SQLITE_API
-+int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file,
-+                                              const char* fileName,
-+                                              int flags,
-+                                              int* fd) {
-+  unixFile* unixSQLite3File = (unixFile*)file;
-+  int fileType = flags & 0xFFFFFF00;
-+  if (fileType == SQLITE_OPEN_MAIN_DB) {
-+    UnixUnusedFd *unusedFd = findReusableFd(fileName, flags);
-+    if (unusedFd) {
-+      *fd = unusedFd->fd;
-+    } else {
-+      unusedFd = sqlite3_malloc(sizeof(*unusedFd));
-+      if (!unusedFd) {
-+        return SQLITE_NOMEM;
-+      }
-+    }
-+    unixSQLite3File->pUnused = unusedFd;
-+  }
-+  return SQLITE_OK;
-+}
-+
-+/*
 +** Marks 'fd' as the unused file descriptor for 'pFile'.
 +*/
 +CHROMIUM_SQLITE_API
@@ -118,7 +88,7 @@
  ** Open the file zPath.
  ** 
  ** Previously, the SQLite OS layer used three functions in place of this
-@@ -5715,20 +5793,13 @@ static int unixOpen(
+@@ -5715,7 +5763,7 @@ static int unixOpen(
      sqlite3_randomness(0,0);
    }
  
@@ -126,24 +96,8 @@
 +  chromium_sqlite3_initialize_unix_sqlite3_file(pFile);
  
    if( eType==SQLITE_OPEN_MAIN_DB ){
--    UnixUnusedFd *pUnused;
--    pUnused = findReusableFd(zName, flags);
--    if( pUnused ){
--      fd = pUnused->fd;
--    }else{
--      pUnused = sqlite3_malloc(sizeof(*pUnused));
--      if( !pUnused ){
--        return SQLITE_NOMEM;
--      }
-+    rc = chromium_sqlite3_get_reusable_file_handle(pFile, zName, flags, &fd);
-+    if( rc!=SQLITE_OK ){
-+      return rc;
-     }
--    p->pUnused = pUnused;
- 
-     /* Database filenames are double-zero terminated if they are not
-     ** URIs with parameters.  Hence, they can always be passed into
-@@ -5798,10 +5869,7 @@ static int unixOpen(
+     UnixUnusedFd *pUnused;
+@@ -5798,10 +5846,7 @@ static int unixOpen(
      *pOutFlags = flags;
    }
  
@@ -155,7 +109,7 @@
  
    if( isDelete ){
  #if OS_VXWORKS
-@@ -5893,7 +5961,7 @@ static int unixOpen(
+@@ -5893,7 +5938,7 @@ static int unixOpen(
  
  open_finished:
    if( rc!=SQLITE_OK ){
@@ -182,10 +136,10 @@
 +
  #endif /* SQLITE_OS_WIN */
 diff --git a/third_party/sqlite/src/src/sqlite.h.in b/third_party/sqlite/src/src/sqlite.h.in
-index f1d4e40..36aa999 100644
+index f1d4e40..00e4771 100644
 --- a/third_party/sqlite/src/src/sqlite.h.in
 +++ b/third_party/sqlite/src/src/sqlite.h.in
-@@ -7408,6 +7408,42 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
+@@ -7408,6 +7408,37 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
  
  
  
@@ -211,11 +165,6 @@
 +                                               const char* fileName,
 +                                               int noLock);
 +CHROMIUM_SQLITE_API
-+int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file,
-+                                              const char* fileName,
-+                                              int flags,
-+                                              int* fd);
-+CHROMIUM_SQLITE_API
 +void chromium_sqlite3_update_reusable_file_handle(sqlite3_file* file,
 +                                                  int fd,
 +                                                  int flags);
@@ -229,5 +178,5 @@
  ** Undo the hack that converts floating point types to integer for
  ** builds on processors without floating point support.
 -- 
-2.4.5
+2.6.1
 
diff --git a/third_party/sqlite/src/src/os_unix.c b/third_party/sqlite/src/src/os_unix.c
index eaa97cf..dc34066 100644
--- a/third_party/sqlite/src/src/os_unix.c
+++ b/third_party/sqlite/src/src/os_unix.c
@@ -5644,36 +5644,6 @@
 }
 
 /*
-** Search for an unused file descriptor that was opened on the database file.
-** If a suitable file descriptor if found, then it is stored in *fd; otherwise,
-** *fd is not modified.
-**
-** If a reusable file descriptor is not found, and a new UnixUnusedFd cannot
-** be allocated, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK is returned.
-*/
-CHROMIUM_SQLITE_API
-int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file,
-                                              const char* fileName,
-                                              int flags,
-                                              int* fd) {
-  unixFile* unixSQLite3File = (unixFile*)file;
-  int fileType = flags & 0xFFFFFF00;
-  if (fileType == SQLITE_OPEN_MAIN_DB) {
-    UnixUnusedFd *unusedFd = findReusableFd(fileName, flags);
-    if (unusedFd) {
-      *fd = unusedFd->fd;
-    } else {
-      unusedFd = sqlite3_malloc(sizeof(*unusedFd));
-      if (!unusedFd) {
-        return SQLITE_NOMEM;
-      }
-    }
-    unixSQLite3File->pUnused = unusedFd;
-  }
-  return SQLITE_OK;
-}
-
-/*
 ** Marks 'fd' as the unused file descriptor for 'pFile'.
 */
 CHROMIUM_SQLITE_API
@@ -5800,10 +5770,17 @@
   chromium_sqlite3_initialize_unix_sqlite3_file(pFile);
 
   if( eType==SQLITE_OPEN_MAIN_DB ){
-    rc = chromium_sqlite3_get_reusable_file_handle(pFile, zName, flags, &fd);
-    if( rc!=SQLITE_OK ){
-      return rc;
+    UnixUnusedFd *pUnused;
+    pUnused = findReusableFd(zName, flags);
+    if( pUnused ){
+      fd = pUnused->fd;
+    }else{
+      pUnused = sqlite3_malloc(sizeof(*pUnused));
+      if( !pUnused ){
+        return SQLITE_NOMEM;
+      }
     }
+    p->pUnused = pUnused;
 
     /* Database filenames are double-zero terminated if they are not
     ** URIs with parameters.  Hence, they can always be passed into
diff --git a/third_party/sqlite/src/src/sqlite.h.in b/third_party/sqlite/src/src/sqlite.h.in
index 333adfe..243835c 100644
--- a/third_party/sqlite/src/src/sqlite.h.in
+++ b/third_party/sqlite/src/src/sqlite.h.in
@@ -7446,11 +7446,6 @@
                                                const char* fileName,
                                                int noLock);
 CHROMIUM_SQLITE_API
-int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file,
-                                              const char* fileName,
-                                              int flags,
-                                              int* fd);
-CHROMIUM_SQLITE_API
 void chromium_sqlite3_update_reusable_file_handle(sqlite3_file* file,
                                                   int fd,
                                                   int flags);
diff --git a/third_party/webrtc_overrides/webrtc/base/logging.cc b/third_party/webrtc_overrides/webrtc/base/logging.cc
index ce4fbd9..34618dac 100644
--- a/third_party/webrtc_overrides/webrtc/base/logging.cc
+++ b/third_party/webrtc_overrides/webrtc/base/logging.cc
@@ -18,12 +18,12 @@
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/threading/platform_thread.h"
-#include "third_party/webrtc/base/ipaddress.h"
-#include "third_party/webrtc/base/stream.h"
 #include "third_party/webrtc/base/stringencode.h"
 #include "third_party/webrtc/base/stringutils.h"
-#include "third_party/webrtc/base/timeutils.h"
+
+// This needs to be included after base/logging.h.
 #include "third_party/webrtc_overrides/webrtc/base/diagnostic_logging.h"
+#include "third_party/webrtc_overrides/webrtc/base/logging.h"
 
 // From this file we can't use VLOG since it expands into usage of the __FILE__
 // macro (for correct filtering). The actual logging call from DIAGNOSTIC_LOG in
@@ -347,9 +347,6 @@
   if (delegate == g_logging_delegate_function)
     return;
   CHECK(!g_logging_delegate_function);
-#ifdef NDEBUG
-  IPAddress::set_strip_sensitive(true);
-#endif
   g_logging_delegate_function = delegate;
 
   if (g_extra_logging_init_function)
diff --git a/tools/grit/grit/util.py b/tools/grit/grit/util.py
index b958bc2..93dce261 100755
--- a/tools/grit/grit/util.py
+++ b/tools/grit/grit/util.py
@@ -483,7 +483,8 @@
   '''Parses a define argument and returns the name and value.
 
   The format is either "NAME=VAL" or "NAME", using True as the default value.
-  Values of "1" and "0" are transformed to True and False respectively.
+  Values of "1"/"true" and "0"/"false" are transformed to True and False
+  respectively.
 
   Args:
     define: a string of the form "NAME=VAL" or "NAME".
@@ -497,8 +498,8 @@
   val = True
   if len(parts) > 1:
     val = parts[1]
-  if val == "1": val = True
-  elif val == "0": val = False
+  if val == "1" or val == "true": val = True
+  elif val == "0" or val == "false": val = False
   return (name, val)
 
 
diff --git a/tools/grit/grit_rule.gni b/tools/grit/grit_rule.gni
index 083e3d93..f60d8fa1 100644
--- a/tools/grit/grit_rule.gni
+++ b/tools/grit/grit_rule.gni
@@ -244,13 +244,6 @@
     "enable_settings_app",
   ]
 }
-if (enable_google_now) {
-  grit_defines += [
-    "-D",
-    "enable_google_now",
-  ]
-}
-
 if (enable_webrtc) {
   grit_defines += [
     "-D",
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 9fbc2d6..20b3484 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -29416,7 +29416,7 @@
   <summary>
     The time from the New Tab page being shown until the user to clicked on a
     most visited tile. Only recorded if the user clicked on a tile, as opposed
-    to e.g. searching via the omnibox.
+    to e.g. searching via the omnibox. Only measured on Android.
   </summary>
 </histogram>
 
@@ -29680,7 +29680,7 @@
   <summary>
     The visual type of each most visited tile displayed on the new tab page,
     e.g. actual thumbnail or placeholder thumbnail. This is recorded for each
-    most visited item when the NTP is opened.
+    most visited item when the NTP is opened. Only measured on Android.
   </summary>
 </histogram>
 
@@ -29688,7 +29688,16 @@
   <owner>newt@chromium.org</owner>
   <summary>
     The visual type of the most visited item that the user clicked on, e.g.
-    actual thumbnail or placeholder thumbnail.
+    actual thumbnail or placeholder thumbnail. Only measured on Android.
+  </summary>
+</histogram>
+
+<histogram name="NewTabPage.TimeSpent" units="milliseconds">
+  <owner>knn@chromium.org</owner>
+  <summary>
+    The time spent on the new tab page as measured from when it was loaded or
+    last brought to the foreground until it was navigated away from or hidden.
+    Only measured on Android.
   </summary>
 </histogram>
 
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn
index 2e0f78c9..6b04ad9 100644
--- a/ui/aura/BUILD.gn
+++ b/ui/aura/BUILD.gn
@@ -66,6 +66,8 @@
     "input_state_lookup_win.h",
     "layout_manager.cc",
     "layout_manager.h",
+    "mus/mus_util.cc",
+    "mus/mus_util.h",
     "remote_window_tree_host_win.cc",
     "remote_window_tree_host_win.h",
     "scoped_window_targeter.cc",
diff --git a/ui/aura/mus/mus_util.cc b/ui/aura/mus/mus_util.cc
new file mode 100644
index 0000000..ed57f6a
--- /dev/null
+++ b/ui/aura/mus/mus_util.cc
@@ -0,0 +1,21 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/aura/mus/mus_util.h"
+
+#include "ui/aura/window.h"
+
+namespace aura {
+
+mus::Window* GetMusWindow(Window* window) {
+  if (!window)
+    return nullptr;
+  return static_cast<mus::Window*>(window->GetNativeWindowProperty("mus"));
+}
+
+void SetMusWindow(Window* window, mus::Window* mus_window) {
+  window->SetNativeWindowProperty("mus", mus_window);
+}
+
+}  // namespace aura
diff --git a/ui/aura/mus/mus_util.h b/ui/aura/mus/mus_util.h
new file mode 100644
index 0000000..a3f2805e
--- /dev/null
+++ b/ui/aura/mus/mus_util.h
@@ -0,0 +1,24 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_AURA_MUS_MUS_UTIL_H_
+#define UI_AURA_MUS_MUS_UTIL_H_
+
+#include "ui/aura/aura_export.h"
+
+namespace mus {
+class Window;
+}
+
+namespace aura {
+
+class Window;
+
+AURA_EXPORT mus::Window* GetMusWindow(Window* window);
+
+AURA_EXPORT void SetMusWindow(Window* window, mus::Window* mus_window);
+
+}  // namespace aura
+
+#endif  // UI_AURA_MUS_MUS_UTIL_H_
diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc
index 5c9f25cd..bb988e1f 100644
--- a/ui/aura/window_tree_host.cc
+++ b/ui/aura/window_tree_host.cc
@@ -102,11 +102,22 @@
   return invert;
 }
 
+void WindowTreeHost::SetOutputSurfacePadding(const gfx::Insets& padding) {
+  if (output_surface_padding_ == padding)
+    return;
+
+  output_surface_padding_ = padding;
+  OnHostResized(GetBounds().size());
+}
+
 void WindowTreeHost::UpdateRootWindowSize(const gfx::Size& host_size) {
-  gfx::Rect bounds(host_size);
+  gfx::Rect bounds(output_surface_padding_.left(),
+                   output_surface_padding_.top(), host_size.width(),
+                   host_size.height());
   gfx::RectF new_bounds(ui::ConvertRectToDIP(window()->layer(), bounds));
   window()->layer()->transform().TransformRect(&new_bounds);
-  window()->SetBounds(gfx::Rect(gfx::ToFlooredSize(new_bounds.size())));
+  window()->SetBounds(gfx::Rect(gfx::ToFlooredPoint(new_bounds.origin()),
+                                gfx::ToFlooredSize(new_bounds.size())));
 }
 
 void WindowTreeHost::ConvertPointToNativeScreen(gfx::Point* point) const {
@@ -259,10 +270,13 @@
 }
 
 void WindowTreeHost::OnHostResized(const gfx::Size& new_size) {
+  gfx::Size adjusted_size(new_size);
+  adjusted_size.Enlarge(output_surface_padding_.width(),
+                        output_surface_padding_.height());
   // The compositor should have the same size as the native root window host.
   // Get the latest scale from display because it might have been changed.
   compositor_->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(window()),
-                               new_size);
+                               adjusted_size);
 
   gfx::Size layer_size = GetBounds().size();
   // The layer, and the observers should be notified of the
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h
index 1571969..31d6904 100644
--- a/ui/aura/window_tree_host.h
+++ b/ui/aura/window_tree_host.h
@@ -13,6 +13,7 @@
 #include "ui/base/cursor/cursor.h"
 #include "ui/base/ime/input_method_delegate.h"
 #include "ui/events/event_source.h"
+#include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/native_widget_types.h"
 
 namespace gfx {
@@ -78,8 +79,19 @@
   virtual void SetRootTransform(const gfx::Transform& transform);
   virtual gfx::Transform GetInverseRootTransform() const;
 
+  // Sets padding applied to the output surface. The output surface is sized to
+  // to the size of the host plus output surface padding. |window()| is offset
+  // by |padding|, that is, |window|'s origin is set to padding.left(),
+  // padding.top().
+  // This does not impact the bounds as returned from GetBounds(), only the
+  // output surface size and location of window(). Additionally window() is
+  // sized to the size set by bounds (more specifically the size passed to
+  // OnHostResized()), but the location of window() is set to that of
+  // |padding|.
+  void SetOutputSurfacePadding(const gfx::Insets& padding);
+
   // Updates the root window's size using |host_size|, current
-  // transform and insets.
+  // transform and outsets.
   virtual void UpdateRootWindowSize(const gfx::Size& host_size);
 
   // Converts |point| from the root window's coordinate system to native
@@ -237,6 +249,8 @@
   // Whether the InputMethod instance is owned by this WindowTreeHost.
   bool owned_input_method_;
 
+  gfx::Insets output_surface_padding_;
+
   DISALLOW_COPY_AND_ASSIGN(WindowTreeHost);
 };
 
diff --git a/ui/file_manager/image_loader/manifest.json b/ui/file_manager/image_loader/manifest.json
index ab0fd83..0d0673f 100644
--- a/ui/file_manager/image_loader/manifest.json
+++ b/ui/file_manager/image_loader/manifest.json
@@ -14,10 +14,11 @@
     "fileManagerPrivate",
     "https://www.google-analytics.com/",
     "https://www.googledrive.com/",
+    "https://lh3.googleusercontent.com/",
     "metricsPrivate",
     "storage"
   ],
-  "content_security_policy": "default-src 'none'; script-src 'self' blob: filesystem: chrome://resources chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj; style-src 'self' blob: filesystem:; frame-src 'self' blob: filesystem:; img-src 'self' blob: filesystem: data:; media-src 'self' blob: filesystem:; connect-src 'self' blob: filesystem: https://www.googledrive.com https://www.google-analytics.com",
+  "content_security_policy": "default-src 'none'; script-src 'self' blob: filesystem: chrome://resources chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj; style-src 'self' blob: filesystem:; frame-src 'self' blob: filesystem:; img-src 'self' blob: filesystem: data:; media-src 'self' blob: filesystem:; connect-src 'self' blob: filesystem: https://www.googledrive.com https://www.google-analytics.com https://lh3.googleusercontent.com",
   "background": {
     "scripts": [
       "chrome://resources/js/assert.js",
diff --git a/ui/message_center/BUILD.gn b/ui/message_center/BUILD.gn
index 850dc2d..de11882 100644
--- a/ui/message_center/BUILD.gn
+++ b/ui/message_center/BUILD.gn
@@ -101,6 +101,8 @@
         "views/message_view_context_menu_controller.h",
         "views/notification_button.cc",
         "views/notification_button.h",
+        "views/notification_progress_bar.cc",
+        "views/notification_progress_bar.h",
         "views/notification_view.cc",
         "views/notification_view.h",
         "views/notifier_settings_view.cc",
diff --git a/ui/message_center/message_center.gyp b/ui/message_center/message_center.gyp
index befef6a..90f6838 100644
--- a/ui/message_center/message_center.gyp
+++ b/ui/message_center/message_center.gyp
@@ -90,6 +90,8 @@
         'views/message_view_context_menu_controller.h',
         'views/notification_button.cc',
         'views/notification_button.h',
+        'views/notification_progress_bar.cc',
+        'views/notification_progress_bar.h',
         'views/notification_view.cc',
         'views/notification_view.h',
         'views/notifier_settings_view.cc',
diff --git a/ui/message_center/views/notification_progress_bar.cc b/ui/message_center/views/notification_progress_bar.cc
new file mode 100644
index 0000000..b5f013e
--- /dev/null
+++ b/ui/message_center/views/notification_progress_bar.cc
@@ -0,0 +1,185 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/message_center/views/notification_progress_bar.h"
+
+#include "third_party/skia/include/core/SkPaint.h"
+#include "third_party/skia/include/core/SkPath.h"
+#include "ui/gfx/canvas.h"
+#include "ui/message_center/message_center_style.h"
+
+namespace {
+
+// Dimensions.
+const int kProgressBarWidth = message_center::kNotificationWidth -
+    message_center::kTextLeftPadding - message_center::kTextRightPadding;
+
+const int kAnimationFrameRateHz = 60;
+
+const int kAnimationDuration = 2000;  // In millisecond
+
+} // namespace
+
+namespace message_center {
+
+// NotificationProgressBarBase /////////////////////////////////////////////////
+
+gfx::Size NotificationProgressBarBase::GetPreferredSize() const {
+  gfx::Size pref_size(kProgressBarWidth, message_center::kProgressBarThickness);
+  gfx::Insets insets = GetInsets();
+  pref_size.Enlarge(insets.width(), insets.height());
+  return pref_size;
+}
+
+// NotificationProgressBar /////////////////////////////////////////////////////
+
+NotificationProgressBar::NotificationProgressBar() {
+}
+
+NotificationProgressBar::~NotificationProgressBar() {
+}
+
+bool NotificationProgressBar::is_indeterminate() {
+  return false;
+}
+
+void NotificationProgressBar::OnPaint(gfx::Canvas* canvas) {
+  gfx::Rect content_bounds = GetContentsBounds();
+
+  // Draw background.
+  SkPath background_path;
+  background_path.addRoundRect(gfx::RectToSkRect(content_bounds),
+                               message_center::kProgressBarCornerRadius,
+                               message_center::kProgressBarCornerRadius);
+  SkPaint background_paint;
+  background_paint.setStyle(SkPaint::kFill_Style);
+  background_paint.setFlags(SkPaint::kAntiAlias_Flag);
+  background_paint.setColor(message_center::kProgressBarBackgroundColor);
+  canvas->DrawPath(background_path, background_paint);
+
+  // Draw slice.
+  SkPath slice_path;
+  const int slice_width =
+      static_cast<int>(content_bounds.width() * GetNormalizedValue() + 0.5);
+  if (slice_width < 1)
+    return;
+
+  gfx::Rect slice_bounds = content_bounds;
+  slice_bounds.set_width(slice_width);
+  slice_path.addRoundRect(gfx::RectToSkRect(slice_bounds),
+                          message_center::kProgressBarCornerRadius,
+                          message_center::kProgressBarCornerRadius);
+
+  SkPaint slice_paint;
+  slice_paint.setStyle(SkPaint::kFill_Style);
+  slice_paint.setFlags(SkPaint::kAntiAlias_Flag);
+  slice_paint.setColor(message_center::kProgressBarSliceColor);
+  canvas->DrawPath(slice_path, slice_paint);
+}
+
+// NotificationIndeteminateProgressBar /////////////////////////////////////////
+
+NotificationIndeterminateProgressBar::NotificationIndeterminateProgressBar() {
+  indeterminate_bar_animation_.reset(
+      new gfx::LinearAnimation(kAnimationFrameRateHz, this));
+  indeterminate_bar_animation_->SetDuration(kAnimationDuration);
+  indeterminate_bar_animation_->Start();
+}
+
+NotificationIndeterminateProgressBar::~NotificationIndeterminateProgressBar() {
+  indeterminate_bar_animation_->Stop();  // Just in case
+}
+
+bool NotificationIndeterminateProgressBar::is_indeterminate() {
+  return true;
+}
+
+void NotificationIndeterminateProgressBar::OnPaint(gfx::Canvas* canvas) {
+  gfx::Rect content_bounds = GetContentsBounds();
+
+  // Draw background.
+  SkPath background_path;
+  background_path.addRoundRect(gfx::RectToSkRect(content_bounds),
+                               message_center::kProgressBarCornerRadius,
+                               message_center::kProgressBarCornerRadius);
+  SkPaint background_paint;
+  background_paint.setStyle(SkPaint::kFill_Style);
+  background_paint.setFlags(SkPaint::kAntiAlias_Flag);
+  background_paint.setColor(message_center::kProgressBarBackgroundColor);
+  canvas->DrawPath(background_path, background_paint);
+
+  // Draw slice.
+  SkPath slice_path;
+  double time = indeterminate_bar_animation_->GetCurrentValue();
+
+  // The animation spec corresponds to the material design lite's parameter.
+  // (cf. https://github.com/google/material-design-lite/)
+  double bar1_left;
+  double bar1_width;
+  double bar2_left;
+  double bar2_width;
+  if (time < 0.50) {
+    bar1_left = time / 2;
+    bar1_width = time * 1.5;
+    bar2_left = 0;
+    bar2_width = 0;
+  } else if (time < 0.75) {
+    bar1_left = time * 3 - 1.25;
+    bar1_width = 0.75 - (time - 0.5)  * 3;
+    bar2_left = 0;
+    bar2_width = time - 0.5;
+  } else {
+    bar1_left = 1;
+    bar1_width = 0;
+    bar2_left = (time - 0.75) * 4;
+    bar2_width = 0.25 - (time - 0.75);
+  }
+
+  int bar1_x = static_cast<int>(content_bounds.width() * bar1_left);
+  int bar1_w =
+      std::min(static_cast<int>(content_bounds.width() * bar1_width + 0.5),
+               content_bounds.width() - bar1_x);
+  int bar2_x = static_cast<int>(content_bounds.width() * bar2_left);
+  int bar2_w =
+      std::min(static_cast<int>(content_bounds.width() * bar2_width + 0.5),
+               content_bounds.width() - bar2_x);
+
+
+  gfx::Rect slice_bounds = content_bounds;
+  slice_bounds.set_x(content_bounds.x() + bar1_x);
+  slice_bounds.set_width(bar1_w);
+  slice_path.addRoundRect(gfx::RectToSkRect(slice_bounds),
+                          message_center::kProgressBarCornerRadius,
+                          message_center::kProgressBarCornerRadius);
+  slice_bounds.set_x(content_bounds.x() + bar2_x);
+  slice_bounds.set_width(bar2_w);
+  slice_path.addRoundRect(gfx::RectToSkRect(slice_bounds),
+                          message_center::kProgressBarCornerRadius,
+                          message_center::kProgressBarCornerRadius);
+
+  SkPaint slice_paint;
+  slice_paint.setStyle(SkPaint::kFill_Style);
+  slice_paint.setFlags(SkPaint::kAntiAlias_Flag);
+  slice_paint.setColor(message_center::kProgressBarSliceColor);
+  canvas->DrawPath(slice_path, slice_paint);
+}
+
+void NotificationIndeterminateProgressBar::AnimationProgressed(
+    const gfx::Animation* animation) {
+  if (animation == indeterminate_bar_animation_.get()) {
+    DCHECK(indeterminate_bar_animation_);
+    SchedulePaint();
+  }
+}
+
+void NotificationIndeterminateProgressBar::AnimationEnded(
+    const gfx::Animation* animation) {
+  // Restarts animation.
+  if (animation == indeterminate_bar_animation_.get()) {
+    DCHECK(indeterminate_bar_animation_);
+    indeterminate_bar_animation_->Start();
+  }
+}
+
+}  // namespace message_center
diff --git a/ui/message_center/views/notification_progress_bar.h b/ui/message_center/views/notification_progress_bar.h
new file mode 100644
index 0000000..4cec162
--- /dev/null
+++ b/ui/message_center/views/notification_progress_bar.h
@@ -0,0 +1,64 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_PROGRESS_BAR_H_
+#define UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_PROGRESS_BAR_H_
+
+#include "base/macros.h"
+#include "ui/gfx/animation/animation_delegate.h"
+#include "ui/gfx/animation/linear_animation.h"
+#include "ui/message_center/message_center_export.h"
+#include "ui/views/controls/progress_bar.h"
+
+namespace message_center {
+
+class MESSAGE_CENTER_EXPORT NotificationProgressBarBase
+    : public views::ProgressBar {
+ public:
+  virtual bool is_indeterminate() = 0;
+
+ private:
+  // Overriden from views::ProgressBar (originally from views::View)
+  gfx::Size GetPreferredSize() const override;
+};
+
+class MESSAGE_CENTER_EXPORT NotificationProgressBar
+    : public NotificationProgressBarBase {
+ public:
+  NotificationProgressBar();
+  ~NotificationProgressBar() override;
+
+  bool is_indeterminate() override;
+
+ private:
+  // Overriden from views::ProgressBar (originally from views::View)
+  void OnPaint(gfx::Canvas* canvas) override;
+
+  DISALLOW_COPY_AND_ASSIGN(NotificationProgressBar);
+};
+
+class MESSAGE_CENTER_EXPORT NotificationIndeterminateProgressBar
+    : public NotificationProgressBarBase, public gfx::AnimationDelegate {
+ public:
+  NotificationIndeterminateProgressBar();
+  ~NotificationIndeterminateProgressBar() override;
+
+  bool is_indeterminate() override;
+
+ private:
+  // Overriden from views::ProgressBar (originally from views::View)
+  void OnPaint(gfx::Canvas* canvas) override;
+
+  // Overriden from gfx::AnimationDelegate
+  void AnimationProgressed(const gfx::Animation* animation) override;
+  void AnimationEnded(const gfx::Animation* animation) override;
+
+  scoped_ptr<gfx::LinearAnimation> indeterminate_bar_animation_;
+
+  DISALLOW_COPY_AND_ASSIGN(NotificationIndeterminateProgressBar);
+};
+
+}  // namespace message_center
+
+#endif  // UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_PROGRESS_BAR_H_
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc
index 76b78276..1bb5392e 100644
--- a/ui/message_center/views/notification_view.cc
+++ b/ui/message_center/views/notification_view.cc
@@ -26,6 +26,7 @@
 #include "ui/message_center/views/constants.h"
 #include "ui/message_center/views/message_center_controller.h"
 #include "ui/message_center/views/notification_button.h"
+#include "ui/message_center/views/notification_progress_bar.h"
 #include "ui/message_center/views/padded_button.h"
 #include "ui/message_center/views/proportional_image_view.h"
 #include "ui/native_theme/native_theme.h"
@@ -48,8 +49,6 @@
 namespace {
 
 // Dimensions.
-const int kProgressBarWidth = message_center::kNotificationWidth -
-    message_center::kTextLeftPadding - message_center::kTextRightPadding;
 const int kProgressBarBottomPadding = 0;
 
 // static
@@ -157,67 +156,6 @@
     child_at(i)->SetVisible(visible);
 }
 
-// NotificationProgressBar /////////////////////////////////////////////////////
-
-class NotificationProgressBar : public views::ProgressBar {
- public:
-  NotificationProgressBar();
-  ~NotificationProgressBar() override;
-
- private:
-  // Overriden from View
-  gfx::Size GetPreferredSize() const override;
-  void OnPaint(gfx::Canvas* canvas) override;
-
-  DISALLOW_COPY_AND_ASSIGN(NotificationProgressBar);
-};
-
-NotificationProgressBar::NotificationProgressBar() {
-}
-
-NotificationProgressBar::~NotificationProgressBar() {
-}
-
-gfx::Size NotificationProgressBar::GetPreferredSize() const {
-  gfx::Size pref_size(kProgressBarWidth, message_center::kProgressBarThickness);
-  gfx::Insets insets = GetInsets();
-  pref_size.Enlarge(insets.width(), insets.height());
-  return pref_size;
-}
-
-void NotificationProgressBar::OnPaint(gfx::Canvas* canvas) {
-  gfx::Rect content_bounds = GetContentsBounds();
-
-  // Draw background.
-  SkPath background_path;
-  background_path.addRoundRect(gfx::RectToSkRect(content_bounds),
-                               message_center::kProgressBarCornerRadius,
-                               message_center::kProgressBarCornerRadius);
-  SkPaint background_paint;
-  background_paint.setStyle(SkPaint::kFill_Style);
-  background_paint.setFlags(SkPaint::kAntiAlias_Flag);
-  background_paint.setColor(message_center::kProgressBarBackgroundColor);
-  canvas->DrawPath(background_path, background_paint);
-
-  // Draw slice.
-  const int slice_width =
-      static_cast<int>(content_bounds.width() * GetNormalizedValue() + 0.5);
-  if (slice_width < 1)
-    return;
-
-  gfx::Rect slice_bounds = content_bounds;
-  slice_bounds.set_width(slice_width);
-  SkPath slice_path;
-  slice_path.addRoundRect(gfx::RectToSkRect(slice_bounds),
-                          message_center::kProgressBarCornerRadius,
-                          message_center::kProgressBarCornerRadius);
-  SkPaint slice_paint;
-  slice_paint.setStyle(SkPaint::kFill_Style);
-  slice_paint.setFlags(SkPaint::kAntiAlias_Flag);
-  slice_paint.setColor(message_center::kProgressBarSliceColor);
-  canvas->DrawPath(slice_path, slice_paint);
-}
-
 }  // namespace
 
 namespace message_center {
@@ -663,14 +601,27 @@
 
   DCHECK(top_view_ != NULL);
 
+  bool is_indeterminate = (notification.progress() < 0);
+  if (progress_bar_view_ &&
+      progress_bar_view_->is_indeterminate() != is_indeterminate) {
+    delete progress_bar_view_;
+    progress_bar_view_ = NULL;
+  }
+
   if (!progress_bar_view_) {
-    progress_bar_view_ = new NotificationProgressBar();
+    if (!is_indeterminate)
+      progress_bar_view_ = new NotificationProgressBar();
+    else
+      progress_bar_view_ = new NotificationIndeterminateProgressBar();
+
     progress_bar_view_->SetBorder(MakeProgressBarBorder(
         message_center::kProgressBarTopPadding, kProgressBarBottomPadding));
     top_view_->AddChildView(progress_bar_view_);
   }
 
-  progress_bar_view_->SetValue(notification.progress() / 100.0);
+  if (!is_indeterminate)
+    progress_bar_view_->SetValue(notification.progress() / 100.0);
+
   progress_bar_view_->SetVisible(!notification.items().size());
 }
 
diff --git a/ui/message_center/views/notification_view.h b/ui/message_center/views/notification_view.h
index 07c47e4b6..2efe8e4 100644
--- a/ui/message_center/views/notification_view.h
+++ b/ui/message_center/views/notification_view.h
@@ -24,6 +24,7 @@
 class MessageCenter;
 class MessageCenterController;
 class NotificationButton;
+class NotificationProgressBarBase;
 class NotificationView;
 class PaddedButton;
 class ProportionalImageView;
@@ -129,7 +130,7 @@
   views::View* bottom_view_;
   views::View* image_container_;
   ProportionalImageView* image_view_;
-  views::ProgressBar* progress_bar_view_;
+  NotificationProgressBarBase* progress_bar_view_;
   std::vector<NotificationButton*> action_buttons_;
   std::vector<views::View*> separators_;
 
diff --git a/ui/views/mus/native_widget_mus.cc b/ui/views/mus/native_widget_mus.cc
index 088cc2e..042f853 100644
--- a/ui/views/mus/native_widget_mus.cc
+++ b/ui/views/mus/native_widget_mus.cc
@@ -13,6 +13,7 @@
 #include "ui/aura/client/window_tree_client.h"
 #include "ui/aura/env.h"
 #include "ui/aura/layout_manager.h"
+#include "ui/aura/mus/mus_util.h"
 #include "ui/aura/window.h"
 #include "ui/base/hit_test.h"
 #include "ui/gfx/canvas.h"
@@ -178,7 +179,10 @@
       show_state_before_fullscreen_(ui::PLATFORM_WINDOW_STATE_UNKNOWN),
       ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
       content_(new aura::Window(this)),
-      close_widget_factory_(this) {}
+      close_widget_factory_(this) {
+  // TODO(fsamuel): Figure out lifetime of |window_|.
+  aura::SetMusWindow(content_, window_);
+}
 
 NativeWidgetMus::~NativeWidgetMus() {
   if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
diff --git a/ui/views/mus/surface_context_factory.cc b/ui/views/mus/surface_context_factory.cc
index 298f1fd1..362d39c4 100644
--- a/ui/views/mus/surface_context_factory.cc
+++ b/ui/views/mus/surface_context_factory.cc
@@ -23,7 +23,8 @@
   void AddMirroringLayer(ui::Layer* layer) override {}
   void RemoveMirroringLayer(ui::Layer* layer) override {}
 };
-}
+
+}  // namespace
 
 SurfaceContextFactory::SurfaceContextFactory(
     mojo::Shell* shell,
diff --git a/ui/views/mus/window_tree_host_mus.h b/ui/views/mus/window_tree_host_mus.h
index 1a4473e..ea3e8fd 100644
--- a/ui/views/mus/window_tree_host_mus.h
+++ b/ui/views/mus/window_tree_host_mus.h
@@ -46,7 +46,7 @@
   PlatformWindowMus* platform_window();
   bitmap_uploader::BitmapUploader* bitmap_uploader() {
     return bitmap_uploader_.get();
-  };
+  }
   ui::PlatformWindowState show_state() const { return show_state_; }
 
  private: