diff --git a/DEPS b/DEPS
index e285c416..7967887 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'd003e24f3f6ef3adeae9d83a62a906247c161bfc',
+  'skia_revision': 'ad1de45fa55676f96434c0c7440c86d7b38af79b',
   # 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': '7448b9f988d16f6a4ba1cf78f59924fcff04dc90',
+  'v8_revision': 'f4848b58865894cecd79d8b0a0a34d17360f7f96',
   # 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.
diff --git a/build/whitespace_file.txt b/build/whitespace_file.txt
index 363a265..0e92db9 100644
--- a/build/whitespace_file.txt
+++ b/build/whitespace_file.txt
@@ -165,4 +165,4 @@
 When I hunger I think of you, and a pastrami sandwich.
 Do make a terrible mistake every once in a while.
 I just made two.
-Mistakes are the best sometimes
+Mistakes are the best sometimes.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/upgrade/PackageReplacedBroadcastReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/upgrade/PackageReplacedBroadcastReceiver.java
index 99b09ffdf..3b8782d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/upgrade/PackageReplacedBroadcastReceiver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/upgrade/PackageReplacedBroadcastReceiver.java
@@ -4,7 +4,6 @@
 
 package org.chromium.chrome.browser.upgrade;
 
-import android.annotation.SuppressLint;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -24,11 +23,10 @@
  * - This class immediately cullable by Android as soon as {@link #onReceive} returns. To kick off
  *   longer tasks, you must start a Service.
  */
-// TODO(crbug.com/635567): Fix this properly.
-@SuppressLint("UnsafeProtectedBroadcastReceiver")
 public final class PackageReplacedBroadcastReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
+        if (!Intent.ACTION_MY_PACKAGE_REPLACED.equals(intent.getAction())) return;
         if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) return;
         UpgradeIntentService.startMigrationIfNecessary(context);
     }
diff --git a/chrome/app/DEPS b/chrome/app/DEPS
index cab9bd2..cc9ceea 100644
--- a/chrome/app/DEPS
+++ b/chrome/app/DEPS
@@ -4,7 +4,7 @@
   "+chrome/child",
   "+chrome/chrome_watcher",
   "+chrome/common/chrome_features.h",
-  "+chrome/installer",
+  "+chrome/installer/util",
   "+chrome/install_static",
   "+chrome/gpu/chrome_content_gpu_client.h",
   "+chrome/renderer/chrome_content_renderer_client.h",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 4c3d004e..7359627 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -6,7 +6,7 @@
   "+chrome/chrome_watcher",
   "+chrome/grit",
   "+chrome/install_static",
-  "+chrome/installer",
+  "+chrome/installer/util",
   "+chrome_elf/blacklist",
   "+chrome_elf/chrome_elf_constants.h",
   "+chrome_elf/dll_hash",
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index a675f43c..d5f2deb 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -3437,7 +3437,13 @@
   ASSERT_TRUE(updated_downloads.empty());
 }
 
-IN_PROC_BROWSER_TEST_F(DownloadTest, FeedbackServiceKeepDownload) {
+// Test is flaky Linux. crbug.com/705224
+#if defined(OS_LINUX)
+#define MAYBE_FeedbackServiceKeepDownload DISABLED_FeedbackServiceKeepDownload
+#else
+#define MAYBE_FeedbackServiceKeepDownload FeedbackServiceKeepDownload
+#endif
+IN_PROC_BROWSER_TEST_F(DownloadTest, MAYBE_FeedbackServiceKeepDownload) {
   PrefService* prefs = browser()->profile()->GetPrefs();
   prefs->SetBoolean(prefs::kSafeBrowsingEnabled, true);
   safe_browsing::SetExtendedReportingPref(prefs, true);
diff --git a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
index 0b387f5..6bf81489 100644
--- a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
+++ b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
@@ -871,8 +871,9 @@
 
 // This test makes sure browser correctly tracks focused editable element inside
 // each RenderFrameHost.
+// Test is flaky. crbug.com/705203
 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest,
-                       TrackingFocusedElementForAllFrames) {
+                       DISABLED_TrackingFocusedElementForAllFrames) {
   CreateIframePage("a(a, b(a))");
   std::vector<content::RenderFrameHost*> frames{
       GetFrame(IndexVector{}), GetFrame(IndexVector{0}),
@@ -912,8 +913,15 @@
 // focused. Then the <input> inside frame is both focused and blurred and  and
 // in both cases the test verifies that WebContents is aware whether or not a
 // focused editable element exists on the page.
+// Test is flaky on ChromeOS. crbug.com/705289
+#if defined(OS_CHROMEOS)
+#define MAYBE_TrackPageFocusEditableElement \
+  DISABLED_TrackPageFocusEditableElement
+#else
+#define MAYBE_TrackPageFocusEditableElement TrackPageFocusEditableElement
+#endif
 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest,
-                       TrackPageFocusEditableElement) {
+                       MAYBE_TrackPageFocusEditableElement) {
   CreateIframePage("a(a, b(a))");
   std::vector<content::RenderFrameHost*> frames{
       GetFrame(IndexVector{}), GetFrame(IndexVector{0}),
@@ -947,8 +955,9 @@
 // WebContents knows about the focused editable element. Then it asks the
 // WebContents to clear focused element and verifies that there is no longer
 // a focused editable element on the page.
+// Test is flaky. crbug.com/705203
 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest,
-                       ClearFocusedElementOnPage) {
+                       DISABLED_ClearFocusedElementOnPage) {
   CreateIframePage("a(a, b(a))");
   std::vector<content::RenderFrameHost*> frames{
       GetFrame(IndexVector{}), GetFrame(IndexVector{0}),
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc
index c7e322c3..0611ded 100644
--- a/chrome/browser/shell_integration_win.cc
+++ b/chrome/browser/shell_integration_win.cc
@@ -48,7 +48,6 @@
 #include "chrome/common/shell_handler_win.mojom.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/install_static/install_util.h"
-#include "chrome/installer/setup/setup_util.h"
 #include "chrome/installer/util/browser_distribution.h"
 #include "chrome/installer/util/install_util.h"
 #include "chrome/installer/util/scoped_user_protocol_entry.h"
diff --git a/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc b/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc
index 2dd4414..83520a2e 100644
--- a/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc
+++ b/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc
@@ -838,7 +838,8 @@
 
 // There is no known way to execute test-controlled tasks during
 // a drag-and-drop loop run by Windows OS.
-#if defined(OS_WIN)
+// Flaky on Linux. crbug.com/704603
+#if defined(OS_WIN) || defined(OS_LINUX)
 #define MAYBE_DragImageBetweenFrames DISABLED_DragImageBetweenFrames
 #else
 #define MAYBE_DragImageBetweenFrames DragImageBetweenFrames
diff --git a/chrome/browser/ui/views/payments/payment_request_can_make_payment_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_can_make_payment_browsertest.cc
index ca68e55..707ddf8 100644
--- a/chrome/browser/ui/views/payments/payment_request_can_make_payment_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_can_make_payment_browsertest.cc
@@ -29,8 +29,9 @@
 };
 
 // Visa is required, and user has a visa instrument.
+// Test is flaky. crbug.com/705225
 IN_PROC_BROWSER_TEST_F(PaymentRequestCanMakePaymentQueryTest,
-                       CanMakePayment_Supported) {
+                       DISABLED_CanMakePayment_Supported) {
   const autofill::CreditCard card = autofill::test::GetCreditCard();  // Visa.
   AddCreditCard(card);
 
@@ -66,8 +67,9 @@
 
 // Visa is required, and user doesn't have a visa instrument and the user is in
 // incognito mode.
+// Test is flaky. crbug.com/705271
 IN_PROC_BROWSER_TEST_F(PaymentRequestCanMakePaymentQueryTest,
-                       CanMakePayment_NotSupported_Incognito) {
+                       DISABLED_CanMakePayment_NotSupported_Incognito) {
   SetIncognitoForTesting();
 
   const autofill::CreditCard card = autofill::test::GetCreditCard2();  // Amex.
diff --git a/chrome/common/DEPS b/chrome/common/DEPS
index 9b6353e..b0596a6d 100644
--- a/chrome/common/DEPS
+++ b/chrome/common/DEPS
@@ -42,7 +42,7 @@
   "+third_party/boringssl/src/include",
 
   # FIXME - refactor code and remove these dependencies
-  "+chrome/installer",
+  "+chrome/installer/util",
 ]
 specific_include_rules = {
   "service_process_util.*": [
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc
index e02d83dbb..f128e0b 100644
--- a/components/autofill/content/renderer/password_form_conversion_utils.cc
+++ b/components/autofill/content/renderer/password_form_conversion_utils.cc
@@ -15,6 +15,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
 #include "base/strings/string16.h"
+#include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/content/renderer/form_autofill_util.h"
@@ -93,6 +94,7 @@
 const char kAutocompleteUsername[] = "username";
 const char kAutocompleteCurrentPassword[] = "current-password";
 const char kAutocompleteNewPassword[] = "new-password";
+const char kAutocompleteCreditCardPrefix[] = "cc-";
 
 re2::RE2* CreateMatcher(void* instance, const char* pattern) {
   re2::RE2::Options options;
@@ -425,6 +427,9 @@
     if (!input_element || !input_element->isEnabled())
       continue;
 
+    if (HasCreditCardAutocompleteAttributes(*input_element))
+      continue;
+
     bool element_is_invisible = !form_util::IsWebNodeVisible(*input_element);
     if (input_element->isTextField()) {
       if (input_element->isPasswordField()) {
@@ -735,12 +740,30 @@
 
 bool HasAutocompleteAttributeValue(const blink::WebInputElement& element,
                                    const char* value_in_lowercase) {
-  base::string16 autocomplete_attribute(
-      element.getAttribute("autocomplete").utf16());
-  std::vector<std::string> tokens = LowercaseAndTokenizeAttributeString(
-      base::UTF16ToUTF8(autocomplete_attribute));
+  std::string autocomplete_value_lowercase = base::ToLowerASCII(
+      base::UTF16ToUTF8(element.getAttribute("autocomplete").utf16()));
+
+  std::vector<base::StringPiece> tokens = base::SplitStringPiece(
+      autocomplete_value_lowercase, base::kWhitespaceASCII,
+      base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
 
   return base::ContainsValue(tokens, value_in_lowercase);
 }
 
+bool HasCreditCardAutocompleteAttributes(
+    const blink::WebInputElement& element) {
+  std::string autocomplete_value_lowercase = base::ToLowerASCII(
+      base::UTF16ToUTF8(element.getAttribute("autocomplete").utf16()));
+
+  for (const auto& token : base::SplitStringPiece(
+           autocomplete_value_lowercase, base::kWhitespaceASCII,
+           base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
+    if (base::StartsWith(token, kAutocompleteCreditCardPrefix,
+                         base::CompareCase::SENSITIVE)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 }  // namespace autofill
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.h b/components/autofill/content/renderer/password_form_conversion_utils.h
index 4c8cd64..0529ac2c 100644
--- a/components/autofill/content/renderer/password_form_conversion_utils.h
+++ b/components/autofill/content/renderer/password_form_conversion_utils.h
@@ -64,6 +64,10 @@
 bool HasAutocompleteAttributeValue(const blink::WebInputElement& element,
                                    const char* value_in_lowercase);
 
+// Checks in a case-insensitive way if credit card autocomplete attributes for
+// the given |element| are present.
+bool HasCreditCardAutocompleteAttributes(const blink::WebInputElement& element);
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_FORM_CONVERSION_UTILS_H__
diff --git a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
index f9d3534..523226b7 100644
--- a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
+++ b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
@@ -1505,4 +1505,37 @@
   EXPECT_FALSE(password_form);
 }
 
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, OnlyCreditCardFields) {
+  PasswordFormBuilder builder(kTestFormActionURL);
+  builder.AddTextField("ccname", "johnsmith", "cc-name");
+  builder.AddPasswordField("cc_security_code", "0123456789", "cc-csc");
+  builder.AddSubmitButton("submit");
+  std::string html = builder.ProduceHTML();
+
+  std::unique_ptr<PasswordForm> password_form =
+      LoadHTMLAndConvertForm(html, nullptr, false);
+  EXPECT_FALSE(password_form);
+}
+
+TEST_F(MAYBE_PasswordFormConversionUtilsTest,
+       FieldsWithAndWithoutCreditCardAttributes) {
+  PasswordFormBuilder builder(kTestFormActionURL);
+  builder.AddTextField("username", "johnsmith", nullptr);
+  builder.AddTextField("ccname", "john_smith", "cc-name");
+  builder.AddPasswordField("cc_security_code", "0123456789", "random cc-csc");
+  builder.AddPasswordField("password", "secret", nullptr);
+  builder.AddSubmitButton("submit");
+  std::string html = builder.ProduceHTML();
+
+  std::unique_ptr<PasswordForm> password_form =
+      LoadHTMLAndConvertForm(html, nullptr, false);
+
+  ASSERT_TRUE(password_form);
+
+  EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
+  EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value);
+  EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
+  EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
+}
+
 }  // namespace autofill
diff --git a/components/doodle/doodle_fetcher_impl.cc b/components/doodle/doodle_fetcher_impl.cc
index af98588..48f6abe 100644
--- a/components/doodle/doodle_fetcher_impl.cc
+++ b/components/doodle/doodle_fetcher_impl.cc
@@ -23,8 +23,6 @@
 
 namespace {
 
-const double kMaxTimeToLiveMS = 30.0 * 24 * 60 * 60 * 1000;  // 30 days
-
 // "/async/ddljson" is the base API path. "ntp:1" identifies this request as
 // being for a New Tab page. The "graybg:" param specifies whether the doodle
 // will be displayed on a gray background.
@@ -148,17 +146,12 @@
       DoodleConfig::FromDictionary(ddljson, GetGoogleBaseUrl());
 
   // The JSON doesn't guarantee the number to fit into an int.
-  double ttl = 0;  // Expires immediately if the parameter is missing.
-  if (!ddljson.GetDouble("time_to_live_ms", &ttl) || ttl < 0) {
+  double ttl_ms = 0;  // Expires immediately if the parameter is missing.
+  if (!ddljson.GetDouble("time_to_live_ms", &ttl_ms) || ttl_ms < 0) {
     DLOG(WARNING) << "No valid Doodle TTL present in ddljson!";
-    ttl = 0;
+    ttl_ms = 0;
   }
-  // TODO(treib,fhorschig): Move this logic into the service.
-  if (ttl > kMaxTimeToLiveMS) {
-    ttl = kMaxTimeToLiveMS;
-    DLOG(WARNING) << "Clamping Doodle TTL to 30 days!";
-  }
-  *time_to_live = base::TimeDelta::FromMillisecondsD(ttl);
+  *time_to_live = base::TimeDelta::FromMillisecondsD(ttl_ms);
 
   return doodle;
 }
diff --git a/components/doodle/doodle_fetcher_impl_unittest.cc b/components/doodle/doodle_fetcher_impl_unittest.cc
index b9908d4..813557a6 100644
--- a/components/doodle/doodle_fetcher_impl_unittest.cc
+++ b/components/doodle/doodle_fetcher_impl_unittest.cc
@@ -198,7 +198,6 @@
         "alt_text":"Mouseover Text",
         "doodle_type":"SIMPLE",
         "interactive_html":"\u003cstyle\u003e\u003c\/style\u003e",
-        "search_url":"/search?q\u003dtest",
         "target_url":"/search?q\u003dtest\u0026sa\u003dX\u0026ved\u003d0ahUKEw",
         "time_to_live_ms":55000,
         "large_image": {
@@ -210,9 +209,6 @@
   ASSERT_TRUE(response.has_value());
   DoodleConfig config = response.value();
 
-  EXPECT_TRUE(config.search_url.is_valid());
-  EXPECT_THAT(config.search_url, Eq(Resolve("/search?q\u003dtest")));
-  EXPECT_TRUE(config.fullpage_interactive_url.is_empty());
   EXPECT_TRUE(config.target_url.is_valid());
   EXPECT_THAT(config.target_url,
               Eq(Resolve("/search?q\u003dtest\u0026sa\u003dX\u0026ved\u003d"
@@ -228,28 +224,6 @@
   EXPECT_THAT(time_to_live, Eq(base::TimeDelta::FromMilliseconds(55000)));
 }
 
-TEST_F(DoodleFetcherImplTest, DoodleExpiresWithinThirtyDaysForTooLargeTTL) {
-  base::MockCallback<DoodleFetcherImpl::FinishedCallback> callback;
-  doodle_fetcher()->FetchDoodle(callback.Get());
-
-  DoodleState state = DoodleState::NO_DOODLE;
-  base::TimeDelta time_to_live;
-  base::Optional<DoodleConfig> response;
-  EXPECT_CALL(callback, Run(_, _, _))
-      .WillOnce(DoAll(SaveArg<0>(&state), SaveArg<1>(&time_to_live),
-                      SaveArg<2>(&response)));
-  RespondWithData(R"json({"ddljson": {
-      "time_to_live_ms":5184000000,
-      "large_image": {"url":"/logos/doodles/2015/some.gif"}
-    }})json");  // 60 days
-
-  EXPECT_THAT(state, Eq(DoodleState::AVAILABLE));
-  EXPECT_TRUE(response.has_value());
-  EXPECT_THAT(time_to_live,
-              Eq(base::TimeDelta::FromMilliseconds(30ul * 24 * 60 * 60 *
-                                                   1000)));  // 30 days
-}
-
 TEST_F(DoodleFetcherImplTest, DoodleExpiresImmediatelyWithNegativeTTL) {
   base::MockCallback<DoodleFetcherImpl::FinishedCallback> callback;
   doodle_fetcher()->FetchDoodle(callback.Get());
diff --git a/components/doodle/doodle_service.cc b/components/doodle/doodle_service.cc
index b005c27..bb97e32 100644
--- a/components/doodle/doodle_service.cc
+++ b/components/doodle/doodle_service.cc
@@ -17,6 +17,12 @@
 
 namespace doodle {
 
+namespace {
+
+const int64_t kMaxTimeToLiveSecs = 30 * 24 * 60 * 60;  // 30 days
+
+}  // namespace
+
 // static
 void DoodleService::RegisterProfilePrefs(PrefRegistrySimple* pref_registry) {
   pref_registry->RegisterDictionaryPref(prefs::kCachedConfig,
@@ -148,6 +154,12 @@
     DoodleState state,
     base::TimeDelta time_to_live,
     const base::Optional<DoodleConfig>& doodle_config) {
+  // Clamp the time-to-live to some reasonable maximum.
+  if (time_to_live.InSeconds() > kMaxTimeToLiveSecs) {
+    time_to_live = base::TimeDelta::FromSeconds(kMaxTimeToLiveSecs);
+    DLOG(WARNING) << "Clamping TTL to " << kMaxTimeToLiveSecs << " seconds!";
+  }
+
   // Handle the case where the new config is already expired.
   bool expired = time_to_live <= base::TimeDelta();
   const base::Optional<DoodleConfig>& new_config =
diff --git a/components/doodle/doodle_service_unittest.cc b/components/doodle/doodle_service_unittest.cc
index ed97819..da7e2541 100644
--- a/components/doodle/doodle_service_unittest.cc
+++ b/components/doodle/doodle_service_unittest.cc
@@ -357,6 +357,20 @@
   service()->RemoveObserver(&observer);
 }
 
+TEST_F(DoodleServiceTest, ClampsTimeToLive) {
+  // Load a config with an excessive time-to-live.
+  service()->Refresh();
+  DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
+  fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
+                               base::TimeDelta::FromDays(100), config);
+  ASSERT_THAT(service()->config(), Eq(config));
+
+  // The time-to-live should have been clamped to a reasonable maximum.
+  ASSERT_THAT(task_runner()->GetPendingTaskCount(), Eq(1u));
+  EXPECT_THAT(task_runner()->NextPendingTaskDelay(),
+              Eq(base::TimeDelta::FromDays(30)));
+}
+
 TEST_F(DoodleServiceTest, RecordsMetricsForSuccessfulDownload) {
   base::HistogramTester histograms;
 
diff --git a/components/doodle/doodle_types.cc b/components/doodle/doodle_types.cc
index 36aa7ec8..3ba743f 100644
--- a/components/doodle/doodle_types.cc
+++ b/components/doodle/doodle_types.cc
@@ -31,9 +31,7 @@
 const char kKeyDoodleType[] = "doodle_type";
 const char kKeyAltText[] = "alt_text";
 const char kKeyInteractiveHtml[] = "interactive_html";
-const char kKeySearchUrl[] = "search_url";
 const char kKeyTargetUrl[] = "target_url";
-const char kKeyFullpageInteractiveUrl[] = "fullpage_interactive_url";
 const char kKeyLargeImage[] = "large_image";
 const char kKeyLargeCtaImage[] = "large_cta_image";
 const char kKeyTransparentLargeImage[] = "transparent_large_image";
@@ -184,10 +182,7 @@
 
   dict.GetString(kKeyInteractiveHtml, &doodle.interactive_html);
 
-  doodle.search_url = ParseUrl(dict, kKeySearchUrl, base_url);
   doodle.target_url = ParseUrl(dict, kKeyTargetUrl, base_url);
-  doodle.fullpage_interactive_url =
-      ParseUrl(dict, kKeyFullpageInteractiveUrl, base_url);
 
   doodle.large_cta_image = ParseImage(dict, kKeyLargeCtaImage, base_url);
   doodle.transparent_large_image =
@@ -201,9 +196,7 @@
   dict->SetString(kKeyDoodleType, DoodleTypeToString(doodle_type));
   dict->SetString(kKeyAltText, alt_text);
   dict->SetString(kKeyInteractiveHtml, interactive_html);
-  dict->SetString(kKeySearchUrl, search_url.spec());
   dict->SetString(kKeyTargetUrl, target_url.spec());
-  dict->SetString(kKeyFullpageInteractiveUrl, fullpage_interactive_url.spec());
   dict->Set(kKeyLargeImage, large_image.ToDictionary());
   if (large_cta_image.has_value()) {
     dict->Set(kKeyLargeCtaImage, large_cta_image->ToDictionary());
@@ -218,8 +211,6 @@
 bool DoodleConfig::operator==(const DoodleConfig& other) const {
   return doodle_type == other.doodle_type && alt_text == other.alt_text &&
          interactive_html == other.interactive_html &&
-         search_url == other.search_url && target_url == other.target_url &&
-         fullpage_interactive_url == other.fullpage_interactive_url &&
          large_image == other.large_image &&
          large_cta_image == other.large_cta_image &&
          transparent_large_image == other.transparent_large_image;
diff --git a/components/doodle/doodle_types.h b/components/doodle/doodle_types.h
index 92ee3ef..66aa2c5 100644
--- a/components/doodle/doodle_types.h
+++ b/components/doodle/doodle_types.h
@@ -77,9 +77,7 @@
   std::string alt_text;
   std::string interactive_html;
 
-  GURL search_url;
   GURL target_url;
-  GURL fullpage_interactive_url;
 
   DoodleImage large_image;
   base::Optional<DoodleImage> large_cta_image;
diff --git a/components/doodle/doodle_types_unittest.cc b/components/doodle/doodle_types_unittest.cc
index d35cdceb..91e2f74 100644
--- a/components/doodle/doodle_types_unittest.cc
+++ b/components/doodle/doodle_types_unittest.cc
@@ -141,9 +141,7 @@
   EXPECT_THAT(config->doodle_type, Eq(DoodleType::UNKNOWN));
   EXPECT_THAT(config->alt_text, Eq(std::string()));
   EXPECT_THAT(config->interactive_html, Eq(std::string()));
-  EXPECT_THAT(config->search_url, Eq(GURL()));
   EXPECT_THAT(config->target_url, Eq(GURL()));
-  EXPECT_THAT(config->fullpage_interactive_url, Eq(GURL()));
   EXPECT_FALSE(config->large_cta_image.has_value());
   EXPECT_FALSE(config->transparent_large_image.has_value());
 }
@@ -153,9 +151,7 @@
         "doodle_type":"SLIDESHOW",
         "alt_text":"some text",
         "interactive_html":"<div id='dood'></div>",
-        "search_url":"https://doodle.com/search",
         "target_url":"https://doodle.com/target",
-        "fullpage_interactive_url":"https://doodle.com/interactive",
         "large_image":{"url":"https://doodle.com/img.jpg"},
         "large_cta_image":{"url":"https://doodle.com/cta.jpg"},
         "transparent_large_image":{"url":"https://doodle.com/transparent.jpg"}
@@ -166,10 +162,7 @@
   EXPECT_THAT(config->doodle_type, Eq(DoodleType::SLIDESHOW));
   EXPECT_THAT(config->alt_text, Eq("some text"));
   EXPECT_THAT(config->interactive_html, Eq("<div id='dood'></div>"));
-  EXPECT_THAT(config->search_url, Eq(GURL("https://doodle.com/search")));
   EXPECT_THAT(config->target_url, Eq(GURL("https://doodle.com/target")));
-  EXPECT_THAT(config->fullpage_interactive_url,
-              Eq(GURL("https://doodle.com/interactive")));
   EXPECT_THAT(config->large_image.url, Eq(GURL("https://doodle.com/img.jpg")));
   ASSERT_TRUE(config->large_cta_image.has_value());
   EXPECT_THAT(config->large_cta_image->url,
@@ -184,9 +177,7 @@
         "doodle_type":"SLIDESHOW",
         "alt_text":"some text",
         "interactive_html":"<div id='dood'></div>",
-        "search_url":"https://doodle.com/search",
         "target_url":"https://doodle.com/target",
-        "fullpage_interactive_url":"https://doodle.com/interactive",
         "large_cta_image":{"url":"https://doodle.com/cta.jpg"},
         "transparent_large_image":{"url":"https://doodle.com/transparent.jpg"}
       })json";
@@ -200,9 +191,7 @@
         "doodle_type":"SLIDESHOW",
         "alt_text":"some text",
         "interactive_html":"<div id='dood'></div>",
-        "search_url":"https://doodle.com/search",
         "target_url":"https://doodle.com/target",
-        "fullpage_interactive_url":"https://doodle.com/interactive",
         "large_image":{"no_url":"asdf"},
         "large_cta_image":{"url":"https://doodle.com/cta.jpg"},
         "transparent_large_image":{"url":"https://doodle.com/transparent.jpg"}
@@ -214,9 +203,7 @@
 
 TEST(DoodleConfigTest, ResolvesRelativeUrls) {
   std::string json = R"json({
-        "search_url":"/search",
         "target_url":"/target",
-        "fullpage_interactive_url":"/interactive",
         "large_image":{"url":"/large.jpg"},
         "large_cta_image":{"url":"/cta.jpg"},
         "transparent_large_image":{"url":"/transparent.jpg"}
@@ -224,10 +211,7 @@
   base::Optional<DoodleConfig> config =
       DoodleConfigFromJson(json, GURL("https://doodle.com/"));
   ASSERT_TRUE(config.has_value());
-  EXPECT_THAT(config->search_url, Eq(GURL("https://doodle.com/search")));
   EXPECT_THAT(config->target_url, Eq(GURL("https://doodle.com/target")));
-  EXPECT_THAT(config->fullpage_interactive_url,
-              Eq(GURL("https://doodle.com/interactive")));
   EXPECT_THAT(config->large_image.url,
               Eq(GURL("https://doodle.com/large.jpg")));
   ASSERT_TRUE(config->large_cta_image.has_value());
@@ -240,18 +224,14 @@
 
 TEST(DoodleConfigTest, HandlesInvalidUrls) {
   std::string json = R"json({
-        "search_url":"not_a_url",
         "target_url":"not_a_url",
-        "fullpage_interactive_url":"not_a_url",
         "large_image":{"url":"https://doodle.com/img.jpg"}
       })json";
   base::Optional<DoodleConfig> config =
       DoodleConfigFromJson(json, base::nullopt);
   // All the URLs are optional, so invalid ones shouldn't matter.
   ASSERT_TRUE(config.has_value());
-  EXPECT_TRUE(config->search_url.is_empty());
   EXPECT_TRUE(config->target_url.is_empty());
-  EXPECT_TRUE(config->fullpage_interactive_url.is_empty());
 }
 
 TEST(DoodleConfigTest, PreservesFieldsOverRoundtrip) {
@@ -260,9 +240,7 @@
                       DoodleImage(GURL("https://www.doodle.com/img.jpg")));
   config.alt_text = "some text";
   config.interactive_html = "<div id='dood'></div>";
-  config.search_url = GURL("https://doodle.com/search");
   config.target_url = GURL("https://doodle.com/target");
-  config.fullpage_interactive_url = GURL("https://doodle.com/interactive");
   config.large_cta_image = DoodleImage(GURL("https://www.doodle.com/cta.jpg"));
   config.transparent_large_image =
       DoodleImage(GURL("https://www.doodle.com/transparent.jpg"));
diff --git a/components/password_manager/core/browser/credential_manager_pending_request_task.cc b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
index 6600bd4..ae1279a 100644
--- a/components/password_manager/core/browser/credential_manager_pending_request_task.cc
+++ b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
@@ -11,6 +11,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/metrics/user_metrics.h"
+#include "base/stl_util.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/affiliated_match_helper.h"
 #include "components/password_manager/core/browser/password_bubble_experiment.h"
@@ -95,15 +96,14 @@
     bool* has_empty_username,
     bool* has_duplicates) {
   // Remove empty usernames from the list.
-  auto begin_empty =
-      std::remove_if(forms->begin(), forms->end(),
-                     [](const std::unique_ptr<autofill::PasswordForm>& form) {
-                       return form->username_value.empty();
-                     });
-  *has_empty_username = (begin_empty != forms->end());
-  forms->erase(begin_empty, forms->end());
+  size_t size_before = forms->size();
+  base::EraseIf(*forms,
+                [](const std::unique_ptr<autofill::PasswordForm>& form) {
+                  return form->username_value.empty();
+                });
+  *has_empty_username = (size_before != forms->size());
 
-  const size_t size_before = forms->size();
+  size_before = forms->size();
   FilterDuplicates(forms);
   *has_duplicates = (size_before != forms->size());
 }
diff --git a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
index e3e2806..90c36a9 100644
--- a/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
+++ b/components/password_manager/core/browser/form_fetcher_impl_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
+#include "base/stl_util.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
@@ -60,12 +61,9 @@
 
   std::vector<std::unique_ptr<PasswordForm>> FilterResults(
       std::vector<std::unique_ptr<PasswordForm>> results) const override {
-    results.erase(
-        std::remove_if(results.begin(), results.end(),
-                       [this](const std::unique_ptr<PasswordForm>& form) {
-                         return !ShouldSave(*form);
-                       }),
-        results.end());
+    base::EraseIf(results, [this](const std::unique_ptr<PasswordForm>& form) {
+      return !ShouldSave(*form);
+    });
     return results;
   }
 
diff --git a/components/password_manager/core/browser/http_password_store_migrator.cc b/components/password_manager/core/browser/http_password_store_migrator.cc
index db243cb..46114572 100644
--- a/components/password_manager/core/browser/http_password_store_migrator.cc
+++ b/components/password_manager/core/browser/http_password_store_migrator.cc
@@ -5,6 +5,7 @@
 #include "components/password_manager/core/browser/http_password_store_migrator.h"
 
 #include "base/memory/weak_ptr.h"
+#include "base/stl_util.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/password_store.h"
@@ -74,13 +75,10 @@
 
 void HttpPasswordStoreMigrator::ProcessPasswordStoreResults() {
   // Android and PSL matches are ignored.
-  results_.erase(
-      std::remove_if(results_.begin(), results_.end(),
-                     [](const std::unique_ptr<autofill::PasswordForm>& form) {
-                       return form->is_affiliation_based_match ||
-                              form->is_public_suffix_match;
-                     }),
-      results_.end());
+  base::EraseIf(
+      results_, [](const std::unique_ptr<autofill::PasswordForm>& form) {
+        return form->is_affiliation_based_match || form->is_public_suffix_match;
+      });
 
   // Add the new credentials to the password store. The HTTP forms are
   // removed iff |mode_| == MigrationMode::MOVE.
diff --git a/components/password_manager/core/browser/obsolete_http_cleaner.cc b/components/password_manager/core/browser/obsolete_http_cleaner.cc
index 06536ddc..cdbe4f2 100644
--- a/components/password_manager/core/browser/obsolete_http_cleaner.cc
+++ b/components/password_manager/core/browser/obsolete_http_cleaner.cc
@@ -10,6 +10,7 @@
 
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
+#include "base/stl_util.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_store.h"
@@ -58,11 +59,9 @@
 void ObsoleteHttpCleaner::OnGetPasswordStoreResults(
     std::vector<std::unique_ptr<PasswordForm>> results) {
   // Non HTTP or HTTPS credentials are ignored.
-  results.erase(std::remove_if(std::begin(results), std::end(results),
-                               [](const std::unique_ptr<PasswordForm>& form) {
-                                 return !form->origin.SchemeIsHTTPOrHTTPS();
-                               }),
-                std::end(results));
+  base::EraseIf(results, [](const std::unique_ptr<PasswordForm>& form) {
+    return !form->origin.SchemeIsHTTPOrHTTPS();
+  });
 
   // Move HTTPS forms into their own container.
   auto https_forms = SplitFormsFrom(
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index 1e570ec..c4ad94d 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -14,6 +14,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
+#include "base/stl_util.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -109,25 +110,16 @@
 
   // Deduplicate.
   std::sort(usernames.begin(), usernames.end());
-  auto new_end = std::unique(usernames.begin(), usernames.end());
+  usernames.erase(std::unique(usernames.begin(), usernames.end()),
+                  usernames.end());
 
-  // Filter out |form->username_value|.
+  // Filter out |form->username_value| and sensitive information.
   const base::string16& username_value = form->username_value;
-  new_end = std::remove_if(usernames.begin(), new_end,
-                           [&username_value](const PossibleUsernamePair& pair) {
-                             return pair.first == username_value;
-                           });
-
-  // Filter out sensitive information.
-  new_end = std::remove_if(
-      usernames.begin(), new_end, [](const PossibleUsernamePair& pair) {
-        return autofill::IsValidCreditCardNumber(pair.first);
-      });
-  new_end = std::remove_if(usernames.begin(), new_end,
-                           [](const PossibleUsernamePair& pair) {
-                             return autofill::IsSSN(pair.first);
-                           });
-  usernames.erase(new_end, usernames.end());
+  base::EraseIf(usernames, [&username_value](const PossibleUsernamePair& pair) {
+    return pair.first == username_value ||
+           autofill::IsValidCreditCardNumber(pair.first) ||
+           autofill::IsSSN(pair.first);
+  });
 }
 
 // Copies field properties masks from the form |from| to the form |to|.
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc
index ae5e3fc3..d8d4eb65 100644
--- a/components/password_manager/core/browser/password_manager_util.cc
+++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 
 #include "base/memory/ptr_util.h"
+#include "base/stl_util.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/log_manager.h"
 #include "components/sync/driver/sync_service.h"
@@ -61,15 +62,12 @@
 void TrimUsernameOnlyCredentials(
     std::vector<std::unique_ptr<autofill::PasswordForm>>* android_credentials) {
   // Remove username-only credentials which are not federated.
-  android_credentials->erase(
-      std::remove_if(
-          android_credentials->begin(), android_credentials->end(),
-          [](const std::unique_ptr<autofill::PasswordForm>& form) {
-            return form->scheme ==
-                       autofill::PasswordForm::SCHEME_USERNAME_ONLY &&
-                   form->federation_origin.unique();
-          }),
-      android_credentials->end());
+  base::EraseIf(*android_credentials,
+                [](const std::unique_ptr<autofill::PasswordForm>& form) {
+                  return form->scheme ==
+                             autofill::PasswordForm::SCHEME_USERNAME_ONLY &&
+                         form->federation_origin.unique();
+                });
 
   // Set "skip_zero_click" on federated credentials.
   std::for_each(
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc
index b9f7f2b..6ccfaad 100644
--- a/components/password_manager/core/browser/password_store.cc
+++ b/components/password_manager/core/browser/password_store.cc
@@ -38,13 +38,10 @@
 void PasswordStore::GetLoginsRequest::NotifyConsumerWithResults(
     std::vector<std::unique_ptr<PasswordForm>> results) {
   if (!ignore_logins_cutoff_.is_null()) {
-    results.erase(
-        std::remove_if(results.begin(), results.end(),
-                       [this](const std::unique_ptr<PasswordForm>& credential) {
-                         return (credential->date_created <
-                                 ignore_logins_cutoff_);
-                       }),
-        results.end());
+    base::EraseIf(results,
+                  [this](const std::unique_ptr<PasswordForm>& credential) {
+                    return (credential->date_created < ignore_logins_cutoff_);
+                  });
   }
 
   origin_task_runner_->PostTask(
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
index 249c4e9..2e52e58 100644
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
+++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
@@ -26,13 +26,6 @@
     Account[] getAccountsByType(String type);
 
     /**
-     * Async version of {@link #getAccountsByType}
-     * This method is deprecated and will be removed soon.
-     */
-    @AnyThread
-    void getAccountsByType(String type, Callback<Account[]> callback);
-
-    /**
      * Get an auth token.
      *
      * @param account The {@link Account} for which the auth token is requested.
@@ -66,13 +59,6 @@
     boolean hasFeatures(Account account, String[] features);
 
     /**
-     * Asynchronous version of {@link #hasFeatures}
-     * This method is deprecated and will be removed soon.
-     */
-    @AnyThread
-    void hasFeatures(Account account, String[] features, Callback<Boolean> callback);
-
-    /**
      * Asks the user to enter a new password for an account, updating the saved credentials for the
      * account.
      * @param account The {@link Account} for which the update is requested.
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerHelper.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerHelper.java
index acfe62cb..abe76c0c 100644
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerHelper.java
+++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerHelper.java
@@ -180,8 +180,18 @@
     /**
      * Retrieves all Google accounts on the device asynchronously.
      */
-    public void getGoogleAccounts(Callback<Account[]> callback) {
-        mAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE, callback);
+    public void getGoogleAccounts(final Callback<Account[]> callback) {
+        new AsyncTask<Void, Void, Account[]>() {
+            @Override
+            protected Account[] doInBackground(Void... params) {
+                return getGoogleAccounts();
+            }
+
+            @Override
+            protected void onPostExecute(Account[] accounts) {
+                callback.onResult(accounts);
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }
 
     /**
@@ -347,8 +357,26 @@
     }
 
     public void checkChildAccount(Account account, Callback<Boolean> callback) {
-        String[] features = {FEATURE_IS_CHILD_ACCOUNT_KEY};
-        mAccountManager.hasFeatures(account, features, callback);
+        hasFeatures(account, new String[] {FEATURE_IS_CHILD_ACCOUNT_KEY}, callback);
+    }
+
+    private boolean hasFeatures(Account account, String[] features) {
+        return mAccountManager.hasFeatures(account, features);
+    }
+
+    private void hasFeatures(
+            final Account account, final String[] features, final Callback<Boolean> callback) {
+        new AsyncTask<Void, Void, Boolean>() {
+            @Override
+            public Boolean doInBackground(Void... params) {
+                return hasFeatures(account, features);
+            }
+
+            @Override
+            public void onPostExecute(Boolean value) {
+                callback.onResult(value);
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }
 
     /**
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
index 6cc91e8..5976779 100644
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
+++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
@@ -15,7 +15,6 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Process;
@@ -64,21 +63,6 @@
     }
 
     @Override
-    public void getAccountsByType(final String type, final Callback<Account[]> callback) {
-        new AsyncTask<Void, Void, Account[]>() {
-            @Override
-            protected Account[] doInBackground(Void... params) {
-                return getAccountsByType(type);
-            }
-
-            @Override
-            protected void onPostExecute(Account[] accounts) {
-                callback.onResult(accounts);
-            }
-        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-    }
-
-    @Override
     public String getAuthToken(Account account, String authTokenScope) throws AuthException {
         assert !ThreadUtils.runningOnUiThread();
         assert AccountManagerHelper.GOOGLE_ACCOUNT_TYPE.equals(account.type);
@@ -128,23 +112,6 @@
         return false;
     }
 
-    @Override
-    public void hasFeatures(
-            final Account account, final String[] features, final Callback<Boolean> callback) {
-        AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
-            @Override
-            public Boolean doInBackground(Void... params) {
-                return hasFeatures(account, features);
-            }
-
-            @Override
-            public void onPostExecute(Boolean value) {
-                callback.onResult(value);
-            }
-        };
-        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-    }
-
     /**
      * Records a histogram value for how long time an action has taken using
      * {@link RecordHistogram#recordTimesHistogram(String, long, TimeUnit))} iff the browser
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/AccountHolder.java b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/AccountHolder.java
index 8f5ccb6..5c361094 100644
--- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/AccountHolder.java
+++ b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/AccountHolder.java
@@ -5,48 +5,36 @@
 package org.chromium.components.signin.test.util;
 
 import android.accounts.Account;
-import android.os.Handler;
 import android.support.annotation.NonNull;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import javax.annotation.Nullable;
-
 /**
  * This class is used by the {@link MockAccountManager} to hold information about a given
  * account, such as its password and set of granted auth tokens.
  */
 public class AccountHolder {
     private final Account mAccount;
-
     private final String mPassword;
-
     private final Map<String, String> mAuthTokens;
-
     private final Map<String, Boolean> mHasBeenAccepted;
-
     private final boolean mAlwaysAccept;
-
-    private Set<String> mFeatures;
-
-    private final List<Runnable> mFeatureCallbacks = new ArrayList<>();
+    private final Set<String> mFeatures;
 
     private AccountHolder(Account account, String password, Map<String, String> authTokens,
-            Map<String, Boolean> hasBeenAccepted, boolean alwaysAccept,
-            @Nullable Set<String> features) {
-        if (account == null) {
-            throw new IllegalArgumentException("Account can not be null");
-        }
+            Map<String, Boolean> hasBeenAccepted, boolean alwaysAccept, Set<String> features) {
+        assert account != null;
+        assert authTokens != null;
+        assert hasBeenAccepted != null;
+        assert features != null;
+
         mAccount = account;
         mPassword = password;
-        mAuthTokens = authTokens == null ? new HashMap<String, String>() : authTokens;
-        mHasBeenAccepted =
-                hasBeenAccepted == null ? new HashMap<String, Boolean>() : hasBeenAccepted;
+        mAuthTokens = authTokens;
+        mHasBeenAccepted = hasBeenAccepted;
         mAlwaysAccept = alwaysAccept;
         mFeatures = features;
     }
@@ -95,46 +83,10 @@
         }
     }
 
-    /**
-     * @return The set of account features. This method may only be called after the account
-     *         features have been fetched.
-     */
     public Set<String> getFeatures() {
-        assert mFeatures != null;
         return mFeatures;
     }
 
-    /**
-     * Adds a callback to be run when the account features have been fetched. If that has already
-     * happened, the callback is run immediately.
-     *
-     * @param callback The callback to be run when the account features have been fetched.
-     */
-    public void addFeaturesCallback(Runnable callback) {
-        if (mFeatures == null) {
-            mFeatureCallbacks.add(callback);
-            return;
-        }
-
-        new Handler().post(callback);
-    }
-
-    /**
-     * Notifies this object that the account features have been fetched.
-     *
-     * @param features The set of account features.
-     */
-    public void didFetchFeatures(Set<String> features) {
-        assert features != null;
-        assert mFeatures == null;
-        mFeatures = features;
-        Handler handler = new Handler();
-        for (Runnable r : mFeatureCallbacks) {
-            handler.post(r);
-        }
-        mFeatureCallbacks.clear();
-    }
-
     @Override
     public int hashCode() {
         return mAccount.hashCode();
@@ -182,67 +134,53 @@
      * Used to construct AccountHolder instances.
      */
     public static class Builder {
-        private Account mTempAccount;
-
-        private String mTempPassword;
-
-        private Map<String, String> mTempAuthTokens;
-
-        private Map<String, Boolean> mTempHasBeenAccepted;
-
-        private boolean mTempAlwaysAccept;
-
+        private Account mAccount;
+        private String mPassword;
+        private Map<String, String> mAuthTokens = new HashMap<>();
+        private Map<String, Boolean> mHasBeenAccepted = new HashMap<>();
+        private boolean mAlwaysAccept;
         private Set<String> mFeatures = new HashSet<>();
 
         public Builder(@NonNull Account account) {
-            mTempAccount = account;
+            mAccount = account;
         }
 
         public Builder account(@NonNull Account account) {
-            mTempAccount = account;
+            mAccount = account;
             return this;
         }
 
         public Builder password(String password) {
-            mTempPassword = password;
+            mPassword = password;
             return this;
         }
 
         public Builder authToken(String authTokenType, String authToken) {
-            if (mTempAuthTokens == null) {
-                mTempAuthTokens = new HashMap<String, String>();
-            }
-            mTempAuthTokens.put(authTokenType, authToken);
+            mAuthTokens.put(authTokenType, authToken);
             return this;
         }
 
-        public Builder authTokens(Map<String, String> authTokens) {
-            mTempAuthTokens = authTokens;
+        public Builder authTokens(@NonNull Map<String, String> authTokens) {
+            mAuthTokens = authTokens;
             return this;
         }
 
         public Builder hasBeenAccepted(String authTokenType, boolean hasBeenAccepted) {
-            if (mTempHasBeenAccepted == null) {
-                mTempHasBeenAccepted = new HashMap<String, Boolean>();
-            }
-            mTempHasBeenAccepted.put(authTokenType, hasBeenAccepted);
+            mHasBeenAccepted.put(authTokenType, hasBeenAccepted);
             return this;
         }
 
-        public Builder hasBeenAcceptedMap(Map<String, Boolean> hasBeenAcceptedMap) {
-            mTempHasBeenAccepted = hasBeenAcceptedMap;
+        public Builder hasBeenAcceptedMap(@NonNull Map<String, Boolean> hasBeenAcceptedMap) {
+            mHasBeenAccepted = hasBeenAcceptedMap;
             return this;
         }
 
         public Builder alwaysAccept(boolean alwaysAccept) {
-            mTempAlwaysAccept = alwaysAccept;
+            mAlwaysAccept = alwaysAccept;
             return this;
         }
 
         public Builder addFeature(String feature) {
-            if (mFeatures == null) {
-                mFeatures = new HashSet<>();
-            }
             mFeatures.add(feature);
             return this;
         }
@@ -250,20 +188,17 @@
         /**
          * Sets the set of features for this account.
          *
-         * @param features The set of account features. Can be null to indicate that the account
-         *            features have not been fetched yet. In this case,
-         *            {@link AccountHolder#didFetchFeatures} should be called on the resulting
-         *            {@link AccountHolder} before the features can be accessed.
+         * @param features The set of account features.
          * @return This object, for chaining method calls.
          */
-        public Builder featureSet(Set<String> features) {
+        public Builder featureSet(@NonNull Set<String> features) {
             mFeatures = features;
             return this;
         }
 
         public AccountHolder build() {
-            return new AccountHolder(mTempAccount, mTempPassword, mTempAuthTokens,
-                    mTempHasBeenAccepted, mTempAlwaysAccept, mFeatures);
+            return new AccountHolder(
+                    mAccount, mPassword, mAuthTokens, mHasBeenAccepted, mAlwaysAccept, mFeatures);
         }
     }
 }
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java
index a7fa0843..7d85711 100644
--- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java
+++ b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java
@@ -8,7 +8,6 @@
 import android.accounts.AuthenticatorDescription;
 import android.app.Activity;
 import android.content.Context;
-import android.os.AsyncTask;
 
 import org.chromium.base.Callback;
 import org.chromium.base.Log;
@@ -73,23 +72,6 @@
         return validAccounts.toArray(new Account[0]);
     }
 
-    @Override
-    public void getAccountsByType(final String type, final Callback<Account[]> callback) {
-        mGetAccountsTaskCounter.increment();
-        new AsyncTask<Void, Void, Account[]>() {
-            @Override
-            protected Account[] doInBackground(Void... params) {
-                return getAccountsByType(type);
-            }
-
-            @Override
-            protected void onPostExecute(Account[] accounts) {
-                callback.onResult(accounts);
-                mGetAccountsTaskCounter.decrement();
-            }
-        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-    }
-
     @VisibleForTesting
     public void waitForGetAccountsTask() throws InterruptedException {
         // Wait until all tasks are done because we don't know which is being waited for.
@@ -170,17 +152,6 @@
     }
 
     @Override
-    public void hasFeatures(
-            final Account account, final String[] features, final Callback<Boolean> callback) {
-        ThreadUtils.postOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                callback.onResult(hasFeatures(account, features));
-            }
-        });
-    }
-
-    @Override
     public void updateCredentials(
             Account account, Activity activity, final Callback<Boolean> callback) {
         ThreadUtils.assertOnUiThread();
diff --git a/components/subresource_filter/core/common/indexed_ruleset.cc b/components/subresource_filter/core/common/indexed_ruleset.cc
index b5455cc..3771632 100644
--- a/components/subresource_filter/core/common/indexed_ruleset.cc
+++ b/components/subresource_filter/core/common/indexed_ruleset.cc
@@ -57,7 +57,7 @@
         if (domain_list_item.exclude())
           domain += '~';
         domain += domain_list_item.domain();
-        domains.push_back(builder->CreateString(domain));
+        domains.push_back(builder->CreateSharedString(domain));
       }
       domains_offset = builder->CreateVector(domains);
     }
@@ -200,7 +200,7 @@
 // RulesetIndexer --------------------------------------------------------------
 
 // static
-const int RulesetIndexer::kIndexedFormatVersion = 11;
+const int RulesetIndexer::kIndexedFormatVersion = 12;
 
 RulesetIndexer::MutableUrlPatternIndex::MutableUrlPatternIndex() = default;
 RulesetIndexer::MutableUrlPatternIndex::~MutableUrlPatternIndex() = default;
@@ -416,6 +416,8 @@
       continue;
     }
 
+    // TODO(pkalinnikov): Match the medatada before the URL pattern, but maybe
+    // excluding the domain list.
     if (DoesRuleMetadataMatch(*rule, initiator, element_type, activation_type,
                               is_third_party, disable_generic_rules)) {
       return true;
diff --git a/components/subresource_filter/core/common/indexed_ruleset_unittest.cc b/components/subresource_filter/core/common/indexed_ruleset_unittest.cc
index a7e4987..e57181f 100644
--- a/components/subresource_filter/core/common/indexed_ruleset_unittest.cc
+++ b/components/subresource_filter/core/common/indexed_ruleset_unittest.cc
@@ -591,6 +591,9 @@
                      .AddDomain("example1.com")
                      .AddDomain("sub.example2.com")
                      .rule()));
+  // Note: Some of the rules have common domains (e.g., example1.com), which are
+  // ultimately shared by FlatBuffers' CreateSharedString. The test also makes
+  // sure that the data structure works properly with such optimization.
 
   Finish();
 
diff --git a/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc b/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
new file mode 100644
index 0000000..5ae9e93
--- /dev/null
+++ b/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
@@ -0,0 +1,84 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h"
+
+#include "base/callback.h"
+#include "base/time/time.h"
+#include "content/common/background_fetch/background_fetch_types.h"
+#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+
+namespace content {
+
+BackgroundFetchEmbeddedWorkerTestHelper::
+    BackgroundFetchEmbeddedWorkerTestHelper()
+    : EmbeddedWorkerTestHelper(base::FilePath() /* in memory */) {}
+
+BackgroundFetchEmbeddedWorkerTestHelper::
+    ~BackgroundFetchEmbeddedWorkerTestHelper() = default;
+
+void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent(
+    const std::string& tag,
+    const mojom::ServiceWorkerEventDispatcher::
+        DispatchBackgroundFetchAbortEventCallback& callback) {
+  last_tag_ = tag;
+
+  if (fail_abort_event_) {
+    callback.Run(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED,
+                 base::Time::Now());
+  } else {
+    callback.Run(SERVICE_WORKER_OK, base::Time::Now());
+  }
+}
+
+void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent(
+    const std::string& tag,
+    mojom::BackgroundFetchState state,
+    const mojom::ServiceWorkerEventDispatcher::
+        DispatchBackgroundFetchClickEventCallback& callback) {
+  last_tag_ = tag;
+  last_state_ = state;
+
+  if (fail_click_event_) {
+    callback.Run(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED,
+                 base::Time::Now());
+  } else {
+    callback.Run(SERVICE_WORKER_OK, base::Time::Now());
+  }
+}
+
+void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent(
+    const std::string& tag,
+    const std::vector<BackgroundFetchSettledFetch>& fetches,
+    const mojom::ServiceWorkerEventDispatcher::
+        DispatchBackgroundFetchFailEventCallback& callback) {
+  last_tag_ = tag;
+  last_fetches_ = fetches;
+
+  if (fail_fail_event_) {
+    callback.Run(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED,
+                 base::Time::Now());
+  } else {
+    callback.Run(SERVICE_WORKER_OK, base::Time::Now());
+  }
+}
+
+void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchedEvent(
+    const std::string& tag,
+    const std::vector<BackgroundFetchSettledFetch>& fetches,
+    const mojom::ServiceWorkerEventDispatcher::
+        DispatchBackgroundFetchedEventCallback& callback) {
+  last_tag_ = tag;
+  last_fetches_ = fetches;
+
+  if (fail_fetched_event_) {
+    callback.Run(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED,
+                 base::Time::Now());
+  } else {
+    callback.Run(SERVICE_WORKER_OK, base::Time::Now());
+  }
+}
+
+}  // namespace content
diff --git a/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h b/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h
new file mode 100644
index 0000000..e9e0a93
--- /dev/null
+++ b/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h
@@ -0,0 +1,84 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_EMBEDDED_WORKER_TEST_HELPER_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_EMBEDDED_WORKER_TEST_HELPER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/optional.h"
+#include "content/browser/service_worker/embedded_worker_test_helper.h"
+
+namespace content {
+
+struct BackgroundFetchSettledFetch;
+
+namespace mojom {
+enum class BackgroundFetchState;
+}
+
+// Extension of the EmbeddedWorkerTestHelper that enables instrumentation of the
+// events related to the Background Fetch API. Storage for these tests will
+// always be kept in memory, as data persistence is tested elsewhere.
+class BackgroundFetchEmbeddedWorkerTestHelper
+    : public EmbeddedWorkerTestHelper {
+ public:
+  BackgroundFetchEmbeddedWorkerTestHelper();
+  ~BackgroundFetchEmbeddedWorkerTestHelper() override;
+
+  // Toggles whether the named Service Worker event should fail.
+  void set_fail_abort_event(bool fail) { fail_abort_event_ = fail; }
+  void set_fail_click_event(bool fail) { fail_click_event_ = fail; }
+  void set_fail_fail_event(bool fail) { fail_fail_event_ = fail; }
+  void set_fail_fetched_event(bool fail) { fail_fetched_event_ = fail; }
+
+  const base::Optional<std::string>& last_tag() const { return last_tag_; }
+  const base::Optional<mojom::BackgroundFetchState>& last_state() const {
+    return last_state_;
+  }
+  const base::Optional<std::vector<BackgroundFetchSettledFetch>> last_fetches()
+      const {
+    return last_fetches_;
+  }
+
+ protected:
+  // EmbeddedWorkerTestHelper overrides:
+  void OnBackgroundFetchAbortEvent(
+      const std::string& tag,
+      const mojom::ServiceWorkerEventDispatcher::
+          DispatchBackgroundFetchAbortEventCallback& callback) override;
+  void OnBackgroundFetchClickEvent(
+      const std::string& tag,
+      mojom::BackgroundFetchState state,
+      const mojom::ServiceWorkerEventDispatcher::
+          DispatchBackgroundFetchClickEventCallback& callback) override;
+  void OnBackgroundFetchFailEvent(
+      const std::string& tag,
+      const std::vector<BackgroundFetchSettledFetch>& fetches,
+      const mojom::ServiceWorkerEventDispatcher::
+          DispatchBackgroundFetchFailEventCallback& callback) override;
+  void OnBackgroundFetchedEvent(
+      const std::string& tag,
+      const std::vector<BackgroundFetchSettledFetch>& fetches,
+      const mojom::ServiceWorkerEventDispatcher::
+          DispatchBackgroundFetchedEventCallback& callback) override;
+
+ private:
+  bool fail_abort_event_ = false;
+  bool fail_click_event_ = false;
+  bool fail_fail_event_ = false;
+  bool fail_fetched_event_ = false;
+
+  base::Optional<std::string> last_tag_;
+  base::Optional<mojom::BackgroundFetchState> last_state_;
+  base::Optional<std::vector<BackgroundFetchSettledFetch>> last_fetches_;
+
+  DISALLOW_COPY_AND_ASSIGN(BackgroundFetchEmbeddedWorkerTestHelper);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_EMBEDDED_WORKER_TEST_HELPER_H_
diff --git a/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc b/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
index 007110e..e80ee7d 100644
--- a/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
@@ -7,233 +7,29 @@
 #include <stdint.h>
 #include <memory>
 
-#include "base/bind.h"
-#include "base/callback.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/optional.h"
 #include "base/run_loop.h"
 #include "base/test/histogram_tester.h"
+#include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h"
 #include "content/browser/background_fetch/background_fetch_registration_id.h"
-#include "content/browser/service_worker/embedded_worker_test_helper.h"
+#include "content/browser/background_fetch/background_fetch_test_base.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/common/background_fetch/background_fetch_types.h"
-#include "content/common/service_worker/service_worker_status_code.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
 namespace {
 
-const char kExampleOrigin[] = "https://example.com/";
-const char kExampleScriptUrl[] = "https://example.com/sw.js";
 const char kExampleTag[] = "my-tag";
 const char kExampleTag2[] = "my-second-tag";
 
-// Extension of the EmbeddedWorkerTestHelper that enables instrumentation of the
-// events related to the Background Fetch API. Storage for these tests will
-// always be kept in memory, as data persistence is tested elsewhere.
-class BackgroundFetchEmbeddedWorkerTestHelper
-    : public EmbeddedWorkerTestHelper {
- public:
-  BackgroundFetchEmbeddedWorkerTestHelper()
-      : EmbeddedWorkerTestHelper(base::FilePath() /* in memory */) {}
-  ~BackgroundFetchEmbeddedWorkerTestHelper() override = default;
-
-  void set_fail_abort_event(bool fail) { fail_abort_event_ = fail; }
-
-  void set_fail_click_event(bool fail) { fail_click_event_ = fail; }
-
-  void set_fail_fail_event(bool fail) { fail_fail_event_ = fail; }
-
-  void set_fail_fetched_event(bool fail) { fail_fetched_event_ = fail; }
-
-  const base::Optional<std::string>& last_tag() const { return last_tag_; }
-  const base::Optional<mojom::BackgroundFetchState>& last_state() const {
-    return last_state_;
-  }
-  const base::Optional<std::vector<BackgroundFetchSettledFetch>> last_fetches()
-      const {
-    return last_fetches_;
-  }
-
- protected:
-  void OnBackgroundFetchAbortEvent(
-      const std::string& tag,
-      const mojom::ServiceWorkerEventDispatcher::
-          DispatchBackgroundFetchAbortEventCallback& callback) override {
-    last_tag_ = tag;
-
-    if (fail_abort_event_) {
-      callback.Run(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED,
-                   base::Time::Now());
-    } else {
-      callback.Run(SERVICE_WORKER_OK, base::Time::Now());
-    }
-  }
-
-  void OnBackgroundFetchClickEvent(
-      const std::string& tag,
-      mojom::BackgroundFetchState state,
-      const mojom::ServiceWorkerEventDispatcher::
-          DispatchBackgroundFetchClickEventCallback& callback) override {
-    last_tag_ = tag;
-    last_state_ = state;
-
-    if (fail_click_event_) {
-      callback.Run(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED,
-                   base::Time::Now());
-    } else {
-      callback.Run(SERVICE_WORKER_OK, base::Time::Now());
-    }
-  }
-
-  void OnBackgroundFetchFailEvent(
-      const std::string& tag,
-      const std::vector<BackgroundFetchSettledFetch>& fetches,
-      const mojom::ServiceWorkerEventDispatcher::
-          DispatchBackgroundFetchFailEventCallback& callback) override {
-    last_tag_ = tag;
-    last_fetches_ = fetches;
-
-    if (fail_fail_event_) {
-      callback.Run(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED,
-                   base::Time::Now());
-    } else {
-      callback.Run(SERVICE_WORKER_OK, base::Time::Now());
-    }
-  }
-
-  void OnBackgroundFetchedEvent(
-      const std::string& tag,
-      const std::vector<BackgroundFetchSettledFetch>& fetches,
-      const mojom::ServiceWorkerEventDispatcher::
-          DispatchBackgroundFetchedEventCallback& callback) override {
-    last_tag_ = tag;
-    last_fetches_ = fetches;
-
-    if (fail_fetched_event_) {
-      callback.Run(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED,
-                   base::Time::Now());
-    } else {
-      callback.Run(SERVICE_WORKER_OK, base::Time::Now());
-    }
-  }
-
- private:
-  bool fail_abort_event_ = false;
-  bool fail_click_event_ = false;
-  bool fail_fail_event_ = false;
-  bool fail_fetched_event_ = false;
-
-  base::Optional<std::string> last_tag_;
-  base::Optional<mojom::BackgroundFetchState> last_state_;
-  base::Optional<std::vector<BackgroundFetchSettledFetch>> last_fetches_;
-
-  DISALLOW_COPY_AND_ASSIGN(BackgroundFetchEmbeddedWorkerTestHelper);
-};
-
-class BackgroundFetchEventDispatcherTest : public ::testing::Test {
+class BackgroundFetchEventDispatcherTest : public BackgroundFetchTestBase {
  public:
   BackgroundFetchEventDispatcherTest()
-      : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
-        event_dispatcher_(embedded_worker_test_helper_.context_wrapper()) {}
+      : event_dispatcher_(embedded_worker_test_helper()->context_wrapper()) {}
+  ~BackgroundFetchEventDispatcherTest() override = default;
 
-  // Creates a new Service Worker registration for a fake origin and scope and
-  // returns the ServiceWorkerRegistration instance associated with it.
-  scoped_refptr<ServiceWorkerRegistration> RegisterServiceWorker() {
-    GURL origin(kExampleOrigin);
-    GURL script_url(kExampleScriptUrl);
-
-    int64_t service_worker_registration_id =
-        kInvalidServiceWorkerRegistrationId;
-
-    {
-      base::RunLoop run_loop;
-      embedded_worker_test_helper_.context()->RegisterServiceWorker(
-          origin, script_url, nullptr /* provider_host */,
-          base::Bind(
-              &BackgroundFetchEventDispatcherTest::DidRegisterServiceWorker,
-              base::Unretained(this), &service_worker_registration_id,
-              run_loop.QuitClosure()));
-
-      run_loop.Run();
-    }
-
-    if (service_worker_registration_id == kInvalidServiceWorkerRegistrationId) {
-      ADD_FAILURE() << "Could not obtain a valid Service Worker registration";
-      return nullptr;
-    }
-
-    scoped_refptr<ServiceWorkerRegistration> service_worker_registration;
-
-    {
-      base::RunLoop run_loop;
-      embedded_worker_test_helper_.context()->storage()->FindRegistrationForId(
-          service_worker_registration_id, origin,
-          base::Bind(&BackgroundFetchEventDispatcherTest::
-                         DidFindServiceWorkerRegistration,
-                     base::Unretained(this), &service_worker_registration,
-                     run_loop.QuitClosure()));
-
-      run_loop.Run();
-    }
-
-    // Wait for the worker to be activated.
-    base::RunLoop().RunUntilIdle();
-
-    if (!service_worker_registration) {
-      ADD_FAILURE() << "Could not find the new Service Worker registration.";
-      return nullptr;
-    }
-
-    return service_worker_registration;
-  }
-
-  // Helper function for getting an url::Origin object with the example origin.
-  url::Origin origin() const { return url::Origin(GURL(kExampleOrigin)); }
-
-  BackgroundFetchEmbeddedWorkerTestHelper* test_helpers() {
-    return &embedded_worker_test_helper_;
-  }
-
-  BackgroundFetchEventDispatcher* dispatcher() { return &event_dispatcher_; }
-
-  base::HistogramTester* histogram_tester() { return &histogram_tester_; }
-
- private:
-  void DidRegisterServiceWorker(int64_t* out_service_worker_registration_id,
-                                base::Closure quit_closure,
-                                ServiceWorkerStatusCode status,
-                                const std::string& status_message,
-                                int64_t service_worker_registration_id) {
-    DCHECK(out_service_worker_registration_id);
-    EXPECT_EQ(SERVICE_WORKER_OK, status) << status_message;
-
-    *out_service_worker_registration_id = service_worker_registration_id;
-
-    quit_closure.Run();
-  }
-
-  void DidFindServiceWorkerRegistration(
-      scoped_refptr<ServiceWorkerRegistration>* out_service_worker_registration,
-      base::Closure quit_closure,
-      ServiceWorkerStatusCode status,
-      scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
-    DCHECK(out_service_worker_registration);
-    EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
-
-    *out_service_worker_registration = service_worker_registration;
-
-    quit_closure.Run();
-  }
-
-  TestBrowserThreadBundle thread_bundle_;
-
-  BackgroundFetchEmbeddedWorkerTestHelper embedded_worker_test_helper_;
+ protected:
   BackgroundFetchEventDispatcher event_dispatcher_;
-
   base::HistogramTester histogram_tester_;
 
   DISALLOW_COPY_AND_ASSIGN(BackgroundFetchEventDispatcherTest);
@@ -244,246 +40,239 @@
       9042 /* random invalid id */, origin(), kExampleTag);
 
   base::RunLoop run_loop;
-  dispatcher()->DispatchBackgroundFetchAbortEvent(invalid_registration_id,
-                                                  run_loop.QuitClosure());
+  event_dispatcher_.DispatchBackgroundFetchAbortEvent(invalid_registration_id,
+                                                      run_loop.QuitClosure());
 
   run_loop.Run();
 
-  histogram_tester()->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.AbortEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_CANNOT_FIND_WORKER, 1);
-  histogram_tester()->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchFailure.FindWorker.AbortEvent",
       SERVICE_WORKER_ERROR_NOT_FOUND, 1);
 }
 
 TEST_F(BackgroundFetchEventDispatcherTest, DispatchAbortEvent) {
-  auto service_worker_registration = RegisterServiceWorker();
-  ASSERT_TRUE(service_worker_registration);
-  ASSERT_TRUE(service_worker_registration->active_version());
-
-  BackgroundFetchRegistrationId registration_id(
-      service_worker_registration->id(), origin(), kExampleTag);
+  BackgroundFetchRegistrationId registration_id;
+  ASSERT_TRUE(CreateRegistrationId(kExampleTag, &registration_id));
 
   {
     base::RunLoop run_loop;
-    dispatcher()->DispatchBackgroundFetchAbortEvent(registration_id,
-                                                    run_loop.QuitClosure());
+    event_dispatcher_.DispatchBackgroundFetchAbortEvent(registration_id,
+                                                        run_loop.QuitClosure());
 
     run_loop.Run();
   }
 
-  ASSERT_TRUE(test_helpers()->last_tag().has_value());
-  EXPECT_EQ(kExampleTag, test_helpers()->last_tag().value());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_tag().has_value());
+  EXPECT_EQ(kExampleTag, embedded_worker_test_helper()->last_tag().value());
 
-  histogram_tester()->ExpectUniqueSample(
+  histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchResult.AbortEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
 
-  test_helpers()->set_fail_abort_event(true);
+  embedded_worker_test_helper()->set_fail_abort_event(true);
 
   BackgroundFetchRegistrationId second_registration_id(
-      service_worker_registration->id(), origin(), kExampleTag2);
+      registration_id.service_worker_registration_id(),
+      registration_id.origin(), kExampleTag2);
 
   {
     base::RunLoop run_loop;
-    dispatcher()->DispatchBackgroundFetchAbortEvent(second_registration_id,
-                                                    run_loop.QuitClosure());
+    event_dispatcher_.DispatchBackgroundFetchAbortEvent(second_registration_id,
+                                                        run_loop.QuitClosure());
 
     run_loop.Run();
   }
 
-  ASSERT_TRUE(test_helpers()->last_tag().has_value());
-  EXPECT_EQ(kExampleTag2, test_helpers()->last_tag().value());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_tag().has_value());
+  EXPECT_EQ(kExampleTag2, embedded_worker_test_helper()->last_tag().value());
 
-  histogram_tester()->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.AbortEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
-  histogram_tester()->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.AbortEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_CANNOT_DISPATCH_EVENT, 1);
-  histogram_tester()->ExpectUniqueSample(
+  histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchFailure.Dispatch.AbortEvent",
       SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, 1);
 }
 
 TEST_F(BackgroundFetchEventDispatcherTest, DispatchClickEvent) {
-  auto service_worker_registration = RegisterServiceWorker();
-  ASSERT_TRUE(service_worker_registration);
-  ASSERT_TRUE(service_worker_registration->active_version());
-
-  BackgroundFetchRegistrationId registration_id(
-      service_worker_registration->id(), origin(), kExampleTag);
+  BackgroundFetchRegistrationId registration_id;
+  ASSERT_TRUE(CreateRegistrationId(kExampleTag, &registration_id));
 
   {
     base::RunLoop run_loop;
-    dispatcher()->DispatchBackgroundFetchClickEvent(
+    event_dispatcher_.DispatchBackgroundFetchClickEvent(
         registration_id, mojom::BackgroundFetchState::PENDING,
         run_loop.QuitClosure());
 
     run_loop.Run();
   }
 
-  ASSERT_TRUE(test_helpers()->last_tag().has_value());
-  EXPECT_EQ(kExampleTag, test_helpers()->last_tag().value());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_tag().has_value());
+  EXPECT_EQ(kExampleTag, embedded_worker_test_helper()->last_tag().value());
 
-  ASSERT_TRUE(test_helpers()->last_state().has_value());
-  EXPECT_EQ(mojom::BackgroundFetchState::PENDING, test_helpers()->last_state());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_state().has_value());
+  EXPECT_EQ(mojom::BackgroundFetchState::PENDING,
+            embedded_worker_test_helper()->last_state());
 
-  histogram_tester()->ExpectUniqueSample(
+  histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchResult.ClickEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
 
-  test_helpers()->set_fail_click_event(true);
+  embedded_worker_test_helper()->set_fail_click_event(true);
 
   BackgroundFetchRegistrationId second_registration_id(
-      service_worker_registration->id(), origin(), kExampleTag2);
+      registration_id.service_worker_registration_id(),
+      registration_id.origin(), kExampleTag2);
 
   {
     base::RunLoop run_loop;
-    dispatcher()->DispatchBackgroundFetchClickEvent(
+    event_dispatcher_.DispatchBackgroundFetchClickEvent(
         second_registration_id, mojom::BackgroundFetchState::SUCCEEDED,
         run_loop.QuitClosure());
 
     run_loop.Run();
   }
 
-  ASSERT_TRUE(test_helpers()->last_tag().has_value());
-  EXPECT_EQ(kExampleTag2, test_helpers()->last_tag().value());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_tag().has_value());
+  EXPECT_EQ(kExampleTag2, embedded_worker_test_helper()->last_tag().value());
 
-  ASSERT_TRUE(test_helpers()->last_state().has_value());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_state().has_value());
   EXPECT_EQ(mojom::BackgroundFetchState::SUCCEEDED,
-            test_helpers()->last_state());
+            embedded_worker_test_helper()->last_state());
 
-  histogram_tester()->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.ClickEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
-  histogram_tester()->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.ClickEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_CANNOT_DISPATCH_EVENT, 1);
-  histogram_tester()->ExpectUniqueSample(
+  histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchFailure.Dispatch.ClickEvent",
       SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, 1);
 }
 
 TEST_F(BackgroundFetchEventDispatcherTest, DispatchFailEvent) {
-  auto service_worker_registration = RegisterServiceWorker();
-  ASSERT_TRUE(service_worker_registration);
-  ASSERT_TRUE(service_worker_registration->active_version());
-
-  BackgroundFetchRegistrationId registration_id(
-      service_worker_registration->id(), origin(), kExampleTag);
+  BackgroundFetchRegistrationId registration_id;
+  ASSERT_TRUE(CreateRegistrationId(kExampleTag, &registration_id));
 
   std::vector<BackgroundFetchSettledFetch> fetches;
   fetches.push_back(BackgroundFetchSettledFetch());
 
   {
     base::RunLoop run_loop;
-    dispatcher()->DispatchBackgroundFetchFailEvent(registration_id, fetches,
-                                                   run_loop.QuitClosure());
+    event_dispatcher_.DispatchBackgroundFetchFailEvent(registration_id, fetches,
+                                                       run_loop.QuitClosure());
 
     run_loop.Run();
   }
 
-  ASSERT_TRUE(test_helpers()->last_tag().has_value());
-  EXPECT_EQ(kExampleTag, test_helpers()->last_tag().value());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_tag().has_value());
+  EXPECT_EQ(kExampleTag, embedded_worker_test_helper()->last_tag().value());
 
-  ASSERT_TRUE(test_helpers()->last_fetches().has_value());
-  EXPECT_EQ(fetches.size(), test_helpers()->last_fetches()->size());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_fetches().has_value());
+  EXPECT_EQ(fetches.size(),
+            embedded_worker_test_helper()->last_fetches()->size());
 
-  histogram_tester()->ExpectUniqueSample(
+  histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchResult.FailEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
 
   fetches.push_back(BackgroundFetchSettledFetch());
 
-  test_helpers()->set_fail_fail_event(true);
+  embedded_worker_test_helper()->set_fail_fail_event(true);
 
   BackgroundFetchRegistrationId second_registration_id(
-      service_worker_registration->id(), origin(), kExampleTag2);
+      registration_id.service_worker_registration_id(),
+      registration_id.origin(), kExampleTag2);
 
   {
     base::RunLoop run_loop;
-    dispatcher()->DispatchBackgroundFetchFailEvent(
+    event_dispatcher_.DispatchBackgroundFetchFailEvent(
         second_registration_id, fetches, run_loop.QuitClosure());
 
     run_loop.Run();
   }
 
-  ASSERT_TRUE(test_helpers()->last_tag().has_value());
-  EXPECT_EQ(kExampleTag2, test_helpers()->last_tag().value());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_tag().has_value());
+  EXPECT_EQ(kExampleTag2, embedded_worker_test_helper()->last_tag().value());
 
-  ASSERT_TRUE(test_helpers()->last_fetches().has_value());
-  EXPECT_EQ(fetches.size(), test_helpers()->last_fetches()->size());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_fetches().has_value());
+  EXPECT_EQ(fetches.size(),
+            embedded_worker_test_helper()->last_fetches()->size());
 
-  histogram_tester()->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.FailEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
-  histogram_tester()->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.FailEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_CANNOT_DISPATCH_EVENT, 1);
-  histogram_tester()->ExpectUniqueSample(
+  histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchFailure.Dispatch.FailEvent",
       SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, 1);
 }
 
 TEST_F(BackgroundFetchEventDispatcherTest, DispatchFetchedEvent) {
-  auto service_worker_registration = RegisterServiceWorker();
-  ASSERT_TRUE(service_worker_registration);
-  ASSERT_TRUE(service_worker_registration->active_version());
-
-  BackgroundFetchRegistrationId registration_id(
-      service_worker_registration->id(), origin(), kExampleTag);
+  BackgroundFetchRegistrationId registration_id;
+  ASSERT_TRUE(CreateRegistrationId(kExampleTag, &registration_id));
 
   std::vector<BackgroundFetchSettledFetch> fetches;
   fetches.push_back(BackgroundFetchSettledFetch());
 
   {
     base::RunLoop run_loop;
-    dispatcher()->DispatchBackgroundFetchedEvent(registration_id, fetches,
-                                                 run_loop.QuitClosure());
+    event_dispatcher_.DispatchBackgroundFetchedEvent(registration_id, fetches,
+                                                     run_loop.QuitClosure());
 
     run_loop.Run();
   }
 
-  ASSERT_TRUE(test_helpers()->last_tag().has_value());
-  EXPECT_EQ(kExampleTag, test_helpers()->last_tag().value());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_tag().has_value());
+  EXPECT_EQ(kExampleTag, embedded_worker_test_helper()->last_tag().value());
 
-  ASSERT_TRUE(test_helpers()->last_fetches().has_value());
-  EXPECT_EQ(fetches.size(), test_helpers()->last_fetches()->size());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_fetches().has_value());
+  EXPECT_EQ(fetches.size(),
+            embedded_worker_test_helper()->last_fetches()->size());
 
-  histogram_tester()->ExpectUniqueSample(
+  histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchResult.FetchedEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
 
   fetches.push_back(BackgroundFetchSettledFetch());
 
-  test_helpers()->set_fail_fetched_event(true);
+  embedded_worker_test_helper()->set_fail_fetched_event(true);
 
   BackgroundFetchRegistrationId second_registration_id(
-      service_worker_registration->id(), origin(), kExampleTag2);
+      registration_id.service_worker_registration_id(),
+      registration_id.origin(), kExampleTag2);
 
   {
     base::RunLoop run_loop;
-    dispatcher()->DispatchBackgroundFetchedEvent(
+    event_dispatcher_.DispatchBackgroundFetchedEvent(
         second_registration_id, fetches, run_loop.QuitClosure());
 
     run_loop.Run();
   }
 
-  ASSERT_TRUE(test_helpers()->last_tag().has_value());
-  EXPECT_EQ(kExampleTag2, test_helpers()->last_tag().value());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_tag().has_value());
+  EXPECT_EQ(kExampleTag2, embedded_worker_test_helper()->last_tag().value());
 
-  ASSERT_TRUE(test_helpers()->last_fetches().has_value());
-  EXPECT_EQ(fetches.size(), test_helpers()->last_fetches()->size());
+  ASSERT_TRUE(embedded_worker_test_helper()->last_fetches().has_value());
+  EXPECT_EQ(fetches.size(),
+            embedded_worker_test_helper()->last_fetches()->size());
 
-  histogram_tester()->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.FetchedEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
-  histogram_tester()->ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.FetchedEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_CANNOT_DISPATCH_EVENT, 1);
-  histogram_tester()->ExpectUniqueSample(
+  histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchFailure.Dispatch.FetchedEvent",
       SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, 1);
 }
diff --git a/content/browser/background_fetch/background_fetch_registration_id.cc b/content/browser/background_fetch/background_fetch_registration_id.cc
index 46d6c679..c334cc5 100644
--- a/content/browser/background_fetch/background_fetch_registration_id.cc
+++ b/content/browser/background_fetch/background_fetch_registration_id.cc
@@ -4,8 +4,13 @@
 
 #include "content/browser/background_fetch/background_fetch_registration_id.h"
 
+#include "content/common/service_worker/service_worker_types.h"
+
 namespace content {
 
+BackgroundFetchRegistrationId::BackgroundFetchRegistrationId()
+    : service_worker_registration_id_(kInvalidServiceWorkerRegistrationId) {}
+
 BackgroundFetchRegistrationId::BackgroundFetchRegistrationId(
     int64_t service_worker_registration_id,
     const url::Origin& origin,
@@ -19,6 +24,9 @@
 
 BackgroundFetchRegistrationId::~BackgroundFetchRegistrationId() = default;
 
+BackgroundFetchRegistrationId& BackgroundFetchRegistrationId::operator=(
+    const BackgroundFetchRegistrationId& other) = default;
+
 bool BackgroundFetchRegistrationId::operator==(
     const BackgroundFetchRegistrationId& other) const {
   return other.service_worker_registration_id_ ==
@@ -38,4 +46,8 @@
          origin_ < other.origin_ || tag_ < other.tag_;
 }
 
+bool BackgroundFetchRegistrationId::is_null() const {
+  return service_worker_registration_id_ == kInvalidServiceWorkerRegistrationId;
+}
+
 }  // namespace content
diff --git a/content/browser/background_fetch/background_fetch_registration_id.h b/content/browser/background_fetch/background_fetch_registration_id.h
index b47f8f5..15851229 100644
--- a/content/browser/background_fetch/background_fetch_registration_id.h
+++ b/content/browser/background_fetch/background_fetch_registration_id.h
@@ -18,12 +18,16 @@
 // to uniquely identify a Background Fetch registration in scope of a profile.
 class CONTENT_EXPORT BackgroundFetchRegistrationId {
  public:
+  BackgroundFetchRegistrationId();
   BackgroundFetchRegistrationId(int64_t service_worker_registration_id,
                                 const url::Origin& origin,
                                 const std::string& tag);
   BackgroundFetchRegistrationId(BackgroundFetchRegistrationId&& other);
   ~BackgroundFetchRegistrationId();
 
+  BackgroundFetchRegistrationId& operator=(
+      const BackgroundFetchRegistrationId& other);
+
   // Returns whether the |other| registration id are identical or different.
   bool operator==(const BackgroundFetchRegistrationId& other) const;
   bool operator!=(const BackgroundFetchRegistrationId& other) const;
@@ -32,6 +36,9 @@
   // TODO(peter): Delete this when we switch away from using maps.
   bool operator<(const BackgroundFetchRegistrationId& other) const;
 
+  // Returns whether this registration id refers to valid data.
+  bool is_null() const;
+
   int64_t service_worker_registration_id() const {
     return service_worker_registration_id_;
   }
@@ -43,7 +50,7 @@
   url::Origin origin_;
   std::string tag_;
 
-  DISALLOW_COPY_AND_ASSIGN(BackgroundFetchRegistrationId);
+  DISALLOW_COPY(BackgroundFetchRegistrationId);
 };
 
 }  // namespace content
diff --git a/content/browser/background_fetch/background_fetch_test_base.cc b/content/browser/background_fetch/background_fetch_test_base.cc
new file mode 100644
index 0000000..2ecb64db
--- /dev/null
+++ b/content/browser/background_fetch/background_fetch_test_base.cc
@@ -0,0 +1,125 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/background_fetch_test_base.h"
+
+#include <stdint.h>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/run_loop.h"
+#include "content/browser/background_fetch/background_fetch_registration_id.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/common/service_worker/service_worker_status_code.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+
+const char kTestOrigin[] = "https://example.com/";
+const char kTestScriptUrl[] = "https://example.com/sw.js";
+
+void DidRegisterServiceWorker(int64_t* out_service_worker_registration_id,
+                              base::Closure quit_closure,
+                              ServiceWorkerStatusCode status,
+                              const std::string& status_message,
+                              int64_t service_worker_registration_id) {
+  DCHECK(out_service_worker_registration_id);
+  EXPECT_EQ(SERVICE_WORKER_OK, status) << status_message;
+
+  *out_service_worker_registration_id = service_worker_registration_id;
+
+  quit_closure.Run();
+}
+
+void DidFindServiceWorkerRegistration(
+    scoped_refptr<ServiceWorkerRegistration>* out_service_worker_registration,
+    base::Closure quit_closure,
+    ServiceWorkerStatusCode status,
+    scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
+  DCHECK(out_service_worker_registration);
+  EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+
+  *out_service_worker_registration = service_worker_registration;
+
+  quit_closure.Run();
+}
+
+}  // namespace
+
+BackgroundFetchTestBase::BackgroundFetchTestBase()
+    : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
+      origin_(GURL(kTestOrigin)) {}
+
+BackgroundFetchTestBase::~BackgroundFetchTestBase() {
+  DCHECK(set_up_called_);
+  DCHECK(tear_down_called_);
+}
+
+void BackgroundFetchTestBase::SetUp() {
+  set_up_called_ = true;
+}
+
+void BackgroundFetchTestBase::TearDown() {
+  service_worker_registrations_.clear();
+  tear_down_called_ = true;
+}
+
+bool BackgroundFetchTestBase::CreateRegistrationId(
+    const std::string& tag,
+    BackgroundFetchRegistrationId* registration_id) {
+  DCHECK(registration_id);
+  DCHECK(registration_id->is_null());
+
+  GURL script_url(kTestScriptUrl);
+
+  int64_t service_worker_registration_id = kInvalidServiceWorkerRegistrationId;
+
+  {
+    base::RunLoop run_loop;
+    embedded_worker_test_helper_.context()->RegisterServiceWorker(
+        origin_.GetURL(), script_url, nullptr /* provider_host */,
+        base::Bind(&DidRegisterServiceWorker, &service_worker_registration_id,
+                   run_loop.QuitClosure()));
+
+    run_loop.Run();
+  }
+
+  if (service_worker_registration_id == kInvalidServiceWorkerRegistrationId) {
+    ADD_FAILURE() << "Could not obtain a valid Service Worker registration";
+    return false;
+  }
+
+  scoped_refptr<ServiceWorkerRegistration> service_worker_registration;
+
+  {
+    base::RunLoop run_loop;
+    embedded_worker_test_helper_.context()->storage()->FindRegistrationForId(
+        service_worker_registration_id, origin_.GetURL(),
+        base::Bind(&DidFindServiceWorkerRegistration,
+                   &service_worker_registration, run_loop.QuitClosure()));
+
+    run_loop.Run();
+  }
+
+  // Wait for the worker to be activated.
+  base::RunLoop().RunUntilIdle();
+
+  if (!service_worker_registration) {
+    ADD_FAILURE() << "Could not find the new Service Worker registration.";
+    return false;
+  }
+
+  *registration_id = BackgroundFetchRegistrationId(
+      service_worker_registration->id(), origin_, tag);
+
+  service_worker_registrations_.push_back(
+      std::move(service_worker_registration));
+  return true;
+}
+
+}  // namespace content
diff --git a/content/browser/background_fetch/background_fetch_test_base.h b/content/browser/background_fetch/background_fetch_test_base.h
new file mode 100644
index 0000000..8f324745
--- /dev/null
+++ b/content/browser/background_fetch/background_fetch_test_base.h
@@ -0,0 +1,71 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_TEST_BASE_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_TEST_BASE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/origin.h"
+
+namespace content {
+
+class BackgroundFetchRegistrationId;
+class ServiceWorkerRegistration;
+
+// Base class containing common functionality needed in unit tests written for
+// the Background Fetch feature.
+class BackgroundFetchTestBase : public ::testing::Test {
+ public:
+  BackgroundFetchTestBase();
+  ~BackgroundFetchTestBase() override;
+
+  // ::testing::Test overrides.
+  void SetUp() override;
+  void TearDown() override;
+
+  // Creates a valid Service Worker registration for the testing origin and
+  // stores the data in the |*registration_id|. Returns whether creation was
+  // successful, which must be asserted by tests.
+  bool CreateRegistrationId(const std::string& tag,
+                            BackgroundFetchRegistrationId* registration_id)
+      WARN_UNUSED_RESULT;
+
+  // Returns the embedded worker test helper instance, which can be used to
+  // influence the behaviour of the Service Worker events.
+  BackgroundFetchEmbeddedWorkerTestHelper* embedded_worker_test_helper() {
+    return &embedded_worker_test_helper_;
+  }
+
+  // Returns the origin that should be used for Background Fetch tests.
+  const url::Origin& origin() const { return origin_; }
+
+ private:
+  TestBrowserThreadBundle thread_bundle_;
+
+  BackgroundFetchEmbeddedWorkerTestHelper embedded_worker_test_helper_;
+
+  url::Origin origin_;
+
+  // Vector of ServiceWorkerRegistration instances that have to be kept alive
+  // for the lifetime of this test.
+  std::vector<scoped_refptr<ServiceWorkerRegistration>>
+      service_worker_registrations_;
+
+  bool set_up_called_ = false;
+  bool tear_down_called_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(BackgroundFetchTestBase);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_TEST_BASE_H_
diff --git a/content/child/webmessageportchannel_impl.cc b/content/child/webmessageportchannel_impl.cc
index 3c5e8d9..7ae8468 100644
--- a/content/child/webmessageportchannel_impl.cc
+++ b/content/child/webmessageportchannel_impl.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "third_party/WebKit/public/platform/WebMessagePortChannel.h"
 #include "third_party/WebKit/public/platform/WebMessagePortChannelClient.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 
@@ -30,11 +31,14 @@
 
 // static
 void WebMessagePortChannelImpl::CreatePair(
-    blink::WebMessagePortChannel** channel1,
-    blink::WebMessagePortChannel** channel2) {
+    std::unique_ptr<blink::WebMessagePortChannel>* channel1,
+    std::unique_ptr<blink::WebMessagePortChannel>* channel2) {
   mojo::MessagePipe pipe;
-  *channel1 = new WebMessagePortChannelImpl(std::move(pipe.handle0));
-  *channel2 = new WebMessagePortChannelImpl(std::move(pipe.handle1));
+  // Constructor is private, so use WrapUnique here.
+  *channel1 =
+      base::WrapUnique(new WebMessagePortChannelImpl(std::move(pipe.handle0)));
+  *channel2 =
+      base::WrapUnique(new WebMessagePortChannelImpl(std::move(pipe.handle1)));
 }
 
 // static
diff --git a/content/child/webmessageportchannel_impl.h b/content/child/webmessageportchannel_impl.h
index 70a04b17..511cd6c 100644
--- a/content/child/webmessageportchannel_impl.h
+++ b/content/child/webmessageportchannel_impl.h
@@ -20,8 +20,9 @@
   ~WebMessagePortChannelImpl() override;
   explicit WebMessagePortChannelImpl(MessagePort message_port);
 
-  static void CreatePair(blink::WebMessagePortChannel** channel1,
-                         blink::WebMessagePortChannel** channel2);
+  static void CreatePair(
+      std::unique_ptr<blink::WebMessagePortChannel>* channel1,
+      std::unique_ptr<blink::WebMessagePortChannel>* channel2);
 
   // Extracts MessagePorts for passing on to other processes.
   static std::vector<MessagePort> ExtractMessagePorts(
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.cc b/content/ppapi_plugin/ppapi_blink_platform_impl.cc
index 92f31e7e..f5b7d5f9 100644
--- a/content/ppapi_plugin/ppapi_blink_platform_impl.cc
+++ b/content/ppapi_plugin/ppapi_blink_platform_impl.cc
@@ -173,11 +173,11 @@
 }
 
 void PpapiBlinkPlatformImpl::createMessageChannel(
-    blink::WebMessagePortChannel** channel1,
-    blink::WebMessagePortChannel** channel2) {
+    std::unique_ptr<blink::WebMessagePortChannel>* channel1,
+    std::unique_ptr<blink::WebMessagePortChannel>* channel2) {
   NOTREACHED();
-  *channel1 = NULL;
-  *channel2 = NULL;
+  *channel1 = nullptr;
+  *channel2 = nullptr;
 }
 
 void PpapiBlinkPlatformImpl::setCookies(
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.h b/content/ppapi_plugin/ppapi_blink_platform_impl.h
index 9c2ba25..1f6fa0d 100644
--- a/content/ppapi_plugin/ppapi_blink_platform_impl.h
+++ b/content/ppapi_plugin/ppapi_blink_platform_impl.h
@@ -32,8 +32,9 @@
   unsigned long long visitedLinkHash(const char* canonicalURL,
                                      size_t length) override;
   bool isLinkVisited(unsigned long long linkHash) override;
-  void createMessageChannel(blink::WebMessagePortChannel** channel1,
-                            blink::WebMessagePortChannel** channel2) override;
+  void createMessageChannel(
+      std::unique_ptr<blink::WebMessagePortChannel>* channel1,
+      std::unique_ptr<blink::WebMessagePortChannel>* channel2) override;
   virtual void setCookies(const blink::WebURL& url,
                           const blink::WebURL& first_party_for_cookies,
                           const blink::WebString& value);
diff --git a/content/renderer/content_security_policy_util.cc b/content/renderer/content_security_policy_util.cc
index 25a09d3c..44d85e2 100644
--- a/content/renderer/content_security_policy_util.cc
+++ b/content/renderer/content_security_policy_util.cc
@@ -37,7 +37,7 @@
 }
 
 ContentSecurityPolicy BuildContentSecurityPolicy(
-    const blink::WebContentSecurityPolicyPolicy& policy) {
+    const blink::WebContentSecurityPolicy& policy) {
   std::vector<CSPDirective> directives;
   for (const auto& directive : policy.directives)
     directives.push_back(BuildCSPDirective(directive));
diff --git a/content/renderer/content_security_policy_util.h b/content/renderer/content_security_policy_util.h
index 03fc62c..46a9a39 100644
--- a/content/renderer/content_security_policy_util.h
+++ b/content/renderer/content_security_policy_util.h
@@ -15,7 +15,7 @@
 // classes represent the exact same thing, but one is in content, the other is
 // in blink.
 ContentSecurityPolicy BuildContentSecurityPolicy(
-    const blink::WebContentSecurityPolicyPolicy&);
+    const blink::WebContentSecurityPolicy&);
 
 // Convert a CSPViolationParams into a WebContentSecurityPolicyViolation. These
 // two classes represent the exact same thing, but one is in content, the other
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 3460c75..1be47e6 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -3257,7 +3257,7 @@
     const blink::WebString& header_value,
     blink::WebContentSecurityPolicyType type,
     blink::WebContentSecurityPolicySource source,
-    const std::vector<blink::WebContentSecurityPolicyPolicy>& policies) {
+    const std::vector<blink::WebContentSecurityPolicy>& policies) {
   ContentSecurityPolicyHeader header;
   header.header_value = header_value.utf8();
   header.type = type;
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 65660d5..ed32ad3 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -531,7 +531,7 @@
       const blink::WebString& header_value,
       blink::WebContentSecurityPolicyType type,
       blink::WebContentSecurityPolicySource source,
-      const std::vector<blink::WebContentSecurityPolicyPolicy>&) override;
+      const std::vector<blink::WebContentSecurityPolicy>&) override;
   void didChangeFrameOwnerProperties(
       blink::WebFrame* child_frame,
       const blink::WebFrameOwnerProperties& frame_owner_properties) override;
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 6593467..8b09758 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -385,8 +385,8 @@
 }
 
 void RendererBlinkPlatformImpl::createMessageChannel(
-    blink::WebMessagePortChannel** channel1,
-    blink::WebMessagePortChannel** channel2) {
+    std::unique_ptr<blink::WebMessagePortChannel>* channel1,
+    std::unique_ptr<blink::WebMessagePortChannel>* channel2) {
   WebMessagePortChannelImpl::CreatePair(channel1, channel2);
 }
 
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index fbff08a..0f272251 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -88,8 +88,9 @@
   unsigned long long visitedLinkHash(const char* canonicalURL,
                                      size_t length) override;
   bool isLinkVisited(unsigned long long linkHash) override;
-  void createMessageChannel(blink::WebMessagePortChannel** channel1,
-                            blink::WebMessagePortChannel** channel2) override;
+  void createMessageChannel(
+      std::unique_ptr<blink::WebMessagePortChannel>* channel1,
+      std::unique_ptr<blink::WebMessagePortChannel>* channel2) override;
   blink::WebPrescientNetworking* prescientNetworking() override;
   void cacheMetadata(const blink::WebURL&,
                      int64_t,
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
index cb5ef55..bd42e96 100644
--- a/content/renderer/shared_worker/embedded_shared_worker_stub.cc
+++ b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -266,7 +266,7 @@
 void EmbeddedSharedWorkerStub::ConnectToChannel(
     int connection_request_id,
     std::unique_ptr<WebMessagePortChannelImpl> channel) {
-  impl_->connect(channel.release());
+  impl_->connect(std::move(channel));
   Send(new WorkerHostMsg_WorkerConnected(connection_request_id, route_id_));
 }
 
diff --git a/content/renderer/shared_worker/shared_worker_repository.cc b/content/renderer/shared_worker/shared_worker_repository.cc
index fe5c846..ee87501 100644
--- a/content/renderer/shared_worker/shared_worker_repository.cc
+++ b/content/renderer/shared_worker/shared_worker_repository.cc
@@ -24,7 +24,7 @@
     blink::WebContentSecurityPolicyType security_policy_type,
     blink::WebAddressSpace creation_address_space,
     blink::WebSharedWorkerCreationContextType creation_context_type,
-    blink::WebMessagePortChannel* channel,
+    std::unique_ptr<blink::WebMessagePortChannel> channel,
     std::unique_ptr<blink::WebSharedWorkerConnectListener> listener) {
   documents_with_workers_.insert(document_id);
 
@@ -40,7 +40,7 @@
   ViewHostMsg_CreateWorker_Reply reply;
 
   // This proxy will self-destruct when a worker is destroyed.
-  new WebSharedWorkerProxy(std::move(listener), params, channel);
+  new WebSharedWorkerProxy(std::move(listener), params, std::move(channel));
 }
 
 void SharedWorkerRepository::documentDetached(DocumentID document) {
diff --git a/content/renderer/shared_worker/shared_worker_repository.h b/content/renderer/shared_worker/shared_worker_repository.h
index 354f0a0..cf9bad3 100644
--- a/content/renderer/shared_worker/shared_worker_repository.h
+++ b/content/renderer/shared_worker/shared_worker_repository.h
@@ -33,7 +33,7 @@
       blink::WebContentSecurityPolicyType,
       blink::WebAddressSpace,
       blink::WebSharedWorkerCreationContextType,
-      blink::WebMessagePortChannel* channel,
+      std::unique_ptr<blink::WebMessagePortChannel> channel,
       std::unique_ptr<blink::WebSharedWorkerConnectListener> listener) override;
   void documentDetached(DocumentID document_id) override;
 
diff --git a/content/renderer/shared_worker/websharedworker_proxy.cc b/content/renderer/shared_worker/websharedworker_proxy.cc
index c0c412f..e5c1b3b 100644
--- a/content/renderer/shared_worker/websharedworker_proxy.cc
+++ b/content/renderer/shared_worker/websharedworker_proxy.cc
@@ -16,11 +16,11 @@
 WebSharedWorkerProxy::WebSharedWorkerProxy(
     std::unique_ptr<blink::WebSharedWorkerConnectListener> listener,
     ViewHostMsg_CreateWorker_Params params,
-    blink::WebMessagePortChannel* channel)
+    std::unique_ptr<blink::WebMessagePortChannel> channel)
     : route_id_(MSG_ROUTING_NONE),
       router_(ChildThreadImpl::current()->GetRouter()),
       listener_(std::move(listener)) {
-  connect(params, channel);
+  connect(params, std::move(channel));
 }
 
 WebSharedWorkerProxy::~WebSharedWorkerProxy() {
@@ -28,8 +28,9 @@
   router_->RemoveRoute(route_id_);
 }
 
-void WebSharedWorkerProxy::connect(ViewHostMsg_CreateWorker_Params params,
-                                   blink::WebMessagePortChannel* channel) {
+void WebSharedWorkerProxy::connect(
+    ViewHostMsg_CreateWorker_Params params,
+    std::unique_ptr<blink::WebMessagePortChannel> channel) {
   // Send synchronous IPC to get |route_id|.
   // TODO(nhiroki): Stop using synchronous IPC (https://crbug.com/679654).
   ViewHostMsg_CreateWorker_Reply reply;
@@ -38,11 +39,8 @@
   router_->AddRoute(route_id_, this);
   listener_->workerCreated(reply.error);
 
-  // Accept ownership of the channel.
-  std::unique_ptr<WebMessagePortChannelImpl> channel_impl(
-      static_cast<WebMessagePortChannelImpl*>(channel));
-
-  message_port_ = channel_impl->ReleaseMessagePort();
+  message_port_ = static_cast<WebMessagePortChannelImpl*>(channel.get())
+                      ->ReleaseMessagePort();
 
   // An actual connection request will be issued on OnWorkerCreated().
 }
diff --git a/content/renderer/shared_worker/websharedworker_proxy.h b/content/renderer/shared_worker/websharedworker_proxy.h
index 3a59a400..b37c00f 100644
--- a/content/renderer/shared_worker/websharedworker_proxy.h
+++ b/content/renderer/shared_worker/websharedworker_proxy.h
@@ -34,12 +34,12 @@
   WebSharedWorkerProxy(
       std::unique_ptr<blink::WebSharedWorkerConnectListener> listener,
       ViewHostMsg_CreateWorker_Params params,
-      blink::WebMessagePortChannel* channel);
+      std::unique_ptr<blink::WebMessagePortChannel> channel);
   ~WebSharedWorkerProxy() override;
 
  private:
   void connect(ViewHostMsg_CreateWorker_Params params,
-               blink::WebMessagePortChannel* channel);
+               std::unique_ptr<blink::WebMessagePortChannel> channel);
 
   // IPC::Listener implementation.
   bool OnMessageReceived(const IPC::Message& message) override;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 09467ff..c11ea38 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -29,6 +29,10 @@
   }
 
   sources = [
+    "../browser/background_fetch/background_fetch_embedded_worker_test_helper.cc",
+    "../browser/background_fetch/background_fetch_embedded_worker_test_helper.h",
+    "../browser/background_fetch/background_fetch_test_base.cc",
+    "../browser/background_fetch/background_fetch_test_base.h",
     "../browser/download/mock_download_file.cc",
     "../browser/download/mock_download_file.h",
     "../browser/download/mock_download_item_impl.cc",
diff --git a/extensions/browser/content_hash_fetcher_unittest.cc b/extensions/browser/content_hash_fetcher_unittest.cc
index 7e16b736..4323d7a9 100644
--- a/extensions/browser/content_hash_fetcher_unittest.cc
+++ b/extensions/browser/content_hash_fetcher_unittest.cc
@@ -221,7 +221,15 @@
 
 // Similar to MissingVerifiedContents, but tests the case where the extension
 // actually has corruption.
-TEST_F(ContentHashFetcherTest, MissingVerifiedContentsAndCorrupt) {
+// Flaky on Linux and ChromeOS. crbug.com/
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#define MAYBE_MissingVerifiedContentsAndCorrupt \
+  DISABLED_MissingVerifiedContentsAndCorrupt
+#else
+#define MAYBE_MissingVerifiedContentsAndCorrupt \
+  MissingVerifiedContentsAndCorrupt
+#endif
+TEST_F(ContentHashFetcherTest, MAYBE_MissingVerifiedContentsAndCorrupt) {
   base::FilePath test_dir_base =
       GetTestPath(base::FilePath()).AppendASCII("missing_verified_contents");
   scoped_refptr<Extension> extension =
diff --git a/mojo/public/interfaces/bindings/BUILD.gn b/mojo/public/interfaces/bindings/BUILD.gn
index c2cadcd7..eab75c1 100644
--- a/mojo/public/interfaces/bindings/BUILD.gn
+++ b/mojo/public/interfaces/bindings/BUILD.gn
@@ -15,15 +15,3 @@
   export_define = "MOJO_CPP_BINDINGS_IMPLEMENTATION"
   export_header = "mojo/public/cpp/bindings/bindings_export.h"
 }
-
-# TODO(yzshen): Remove this target and use the one above once
-# |use_new_js_bindings| becomes true by default.
-mojom("new_bindings") {
-  visibility = []
-  sources = [
-    "new_bindings/interface_control_messages.mojom",
-    "new_bindings/pipe_control_messages.mojom",
-  ]
-
-  use_new_js_bindings = true
-}
diff --git a/mojo/public/interfaces/bindings/new_bindings/OWNERS b/mojo/public/interfaces/bindings/new_bindings/OWNERS
deleted file mode 100644
index 08850f4..0000000
--- a/mojo/public/interfaces/bindings/new_bindings/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/mojo/public/interfaces/bindings/new_bindings/interface_control_messages.mojom b/mojo/public/interfaces/bindings/new_bindings/interface_control_messages.mojom
deleted file mode 100644
index e03ffd6..0000000
--- a/mojo/public/interfaces/bindings/new_bindings/interface_control_messages.mojom
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-[JavaPackage="org.chromium.mojo.bindings.interfacecontrol"]
-module mojo.interface_control2;
-
-// For each user-defined interface, some control functions are provided by the
-// interface endpoints at both sides.
-
-////////////////////////////////////////////////////////////////////////////////
-// Run@0xFFFFFFFF(RunInput input) => (RunOutput? output);
-//
-// This control function runs the input command. If the command is not
-// supported, |output| is set to null; otherwise |output| stores the result,
-// whose type depends on the input.
-
-const uint32 kRunMessageId = 0xFFFFFFFF;
-
-struct RunMessageParams {
-  RunInput input;
-};
-union RunInput {
-  QueryVersion query_version;
-  FlushForTesting flush_for_testing;
-};
-
-struct RunResponseMessageParams {
-  RunOutput? output;
-};
-union RunOutput {
-  QueryVersionResult query_version_result;
-};
-
-// Queries the max supported version of the user-defined interface.
-// Sent by the interface client side.
-struct QueryVersion {
-};
-struct QueryVersionResult {
-  uint32 version;
-};
-
-// Sent by either side of the interface.
-struct FlushForTesting {
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// RunOrClosePipe@0xFFFFFFFE(RunOrClosePipeInput input);
-//
-// This control function runs the input command. If the operation fails or the
-// command is not supported, the message pipe is closed.
-
-const uint32 kRunOrClosePipeMessageId = 0xFFFFFFFE;
-
-struct RunOrClosePipeMessageParams {
-  RunOrClosePipeInput input;
-};
-union RunOrClosePipeInput {
-  RequireVersion require_version;
-};
-
-// If the specified version of the user-defined interface is not supported, the
-// function fails and the pipe is closed.
-// Sent by the interface client side.
-struct RequireVersion {
-  uint32 version;
-};
diff --git a/mojo/public/interfaces/bindings/new_bindings/pipe_control_messages.mojom b/mojo/public/interfaces/bindings/new_bindings/pipe_control_messages.mojom
deleted file mode 100644
index 69975fc1..0000000
--- a/mojo/public/interfaces/bindings/new_bindings/pipe_control_messages.mojom
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-[JavaPackage="org.chromium.mojo.bindings.pipecontrol"]
-module mojo.pipe_control2;
-
-// For each message pipe running user-defined interfaces, some control
-// functions are provided and used by the routers at both ends of the pipe, so
-// that they can coordinate to manage interface endpoints.
-// All these control messages will have the interface ID field in the message
-// header set to invalid.
-
-////////////////////////////////////////////////////////////////////////////////
-// RunOrClosePipe@0xFFFFFFFE(RunOrClosePipeInput input);
-//
-// This control function runs the input command. If the operation fails or the
-// command is not supported, the message pipe is closed.
-
-const uint32 kRunOrClosePipeMessageId = 0xFFFFFFFE;
-
-struct RunOrClosePipeMessageParams {
-  RunOrClosePipeInput input;
-};
-
-union RunOrClosePipeInput {
-  PeerAssociatedEndpointClosedEvent peer_associated_endpoint_closed_event;
-};
-
-// A user-defined reason about why the interface is disconnected.
-struct DisconnectReason {
-  uint32 custom_reason;
-  string description;
-};
-
-// An event to notify that an interface endpoint set up at the message sender
-// side has been closed.
-//
-// This event is omitted if the endpoint belongs to the master interface and
-// there is no disconnect reason specified.
-struct PeerAssociatedEndpointClosedEvent {
-  // The interface ID.
-  uint32 id;
-  DisconnectReason? disconnect_reason;
-};
-
diff --git a/mojo/public/interfaces/bindings/tests/BUILD.gn b/mojo/public/interfaces/bindings/tests/BUILD.gn
index e496eb65..0e086c3 100644
--- a/mojo/public/interfaces/bindings/tests/BUILD.gn
+++ b/mojo/public/interfaces/bindings/tests/BUILD.gn
@@ -27,7 +27,6 @@
     "validation_test_interfaces.mojom",
   ]
   public_deps = [
-    ":echo",
     ":test_mojom_import",
     ":test_mojom_import2",
   ]
@@ -193,12 +192,3 @@
     ":test_interfaces",
   ]
 }
-
-mojom("echo") {
-  testonly = true
-  sources = [
-    "echo.mojom",
-    "echo_import.mojom",
-  ]
-  use_new_js_bindings = true
-}
diff --git a/mojo/public/interfaces/bindings/tests/echo.mojom b/mojo/public/interfaces/bindings/tests/echo.mojom
deleted file mode 100644
index 56c60630..0000000
--- a/mojo/public/interfaces/bindings/tests/echo.mojom
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module test.echo.mojom;
-
-import "echo_import.mojom";
-
-interface Echo {
-  EchoPoint(test.echo_import.mojom.Point point)
-      => (test.echo_import.mojom.Point result);
-};
diff --git a/mojo/public/interfaces/bindings/tests/echo_import.mojom b/mojo/public/interfaces/bindings/tests/echo_import.mojom
deleted file mode 100644
index a024ce2f..0000000
--- a/mojo/public/interfaces/bindings/tests/echo_import.mojom
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module test.echo_import.mojom;
-
-struct Point {
-  int32 x;
-  int32 y;
-};
diff --git a/mojo/public/js/BUILD.gn b/mojo/public/js/BUILD.gn
index 5c8f12e0..6c8fbee 100644
--- a/mojo/public/js/BUILD.gn
+++ b/mojo/public/js/BUILD.gn
@@ -30,48 +30,10 @@
   ]
 
   deps = [
-    ":new_bindings",
     "//mojo/public/interfaces/bindings:bindings__generator",
   ]
 }
 
-action("new_bindings") {
-  new_bindings_js_files = [
-    # This must be the first file in the list, because it initializes global
-    # variable |mojoBindings| that the others need to refer to.
-    "new_bindings/base.js",
-
-    "$interfaces_bindings_gen_dir/new_bindings/interface_control_messages.mojom.js",
-    "new_bindings/bindings.js",
-    "new_bindings/buffer.js",
-    "new_bindings/codec.js",
-    "new_bindings/connector.js",
-    "new_bindings/interface_types.js",
-    "new_bindings/lib/control_message_handler.js",
-    "new_bindings/lib/control_message_proxy.js",
-    "new_bindings/router.js",
-    "new_bindings/unicode.js",
-    "new_bindings/validator.js",
-  ]
-  compiled_file = "$target_gen_dir/mojo_bindings.js"
-
-  # TODO(yzshen): Eventually we would like to use Closure Compiler to minify the
-  # bindings instead of simply concatenating the files.
-  script = "//v8/tools/concatenate-files.py"
-
-  sources = new_bindings_js_files
-  outputs = [
-    compiled_file,
-  ]
-
-  args = rebase_path(new_bindings_js_files)
-  args += [ rebase_path(compiled_file) ]
-
-  deps = [
-    "//mojo/public/interfaces/bindings:new_bindings__generator",
-  ]
-}
-
 group("tests") {
   testonly = true
 
diff --git a/mojo/public/js/new_bindings/base.js b/mojo/public/js/new_bindings/base.js
deleted file mode 100644
index c147ec6..0000000
--- a/mojo/public/js/new_bindings/base.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-if (mojoBindings) {
-  throw new Error('mojoBindings has been initialized.');
-}
-
-var mojoBindings = {};
-mojoBindings.internal = {};
-mojoBindings.internal.global = this;
-
-(function() {
-  var internal = mojoBindings.internal;
-
-  function exposeNamespace(namespace) {
-    var current = internal.global;
-    var parts = namespace.split('.');
-
-    for (var part; parts.length && (part = parts.shift());) {
-      if (!current[part]) {
-        current[part] = {};
-      }
-      current = current[part];
-    }
-
-    return current;
-  }
-
-  internal.exposeNamespace = exposeNamespace;
-})();
diff --git a/mojo/public/js/new_bindings/bindings.js b/mojo/public/js/new_bindings/bindings.js
index 8dcb946e..f3e40d29 100644
--- a/mojo/public/js/new_bindings/bindings.js
+++ b/mojo/public/js/new_bindings/bindings.js
@@ -2,14 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
-  var internal = mojoBindings.internal;
+define("mojo/public/js/bindings", [
+  "mojo/public/js/core",
+  "mojo/public/js/lib/control_message_proxy",
+  "mojo/public/js/interface_types",
+  "mojo/public/js/router",
+], function(core, controlMessageProxy, types, router) {
+
   // ---------------------------------------------------------------------------
 
   function makeRequest(interfacePtr) {
-    var pipe = Mojo.createMessagePipe();
-    interfacePtr.ptr.bind(new mojoBindings.InterfacePtrInfo(pipe.handle0, 0));
-    return new mojoBindings.InterfaceRequest(pipe.handle1);
+    var pipe = core.createMessagePipe();
+    interfacePtr.ptr.bind(new types.InterfacePtrInfo(pipe.handle0, 0));
+    return new types.InterfaceRequest(pipe.handle1);
   }
 
   // ---------------------------------------------------------------------------
@@ -36,7 +41,7 @@
   InterfacePtrController.prototype.bind = function(ptrInfoOrHandle) {
     this.reset();
 
-    if (ptrInfoOrHandle instanceof mojoBindings.InterfacePtrInfo) {
+    if (ptrInfoOrHandle instanceof types.InterfacePtrInfo) {
       this.version = ptrInfoOrHandle.version;
       this.handle_ = ptrInfoOrHandle.handle;
     } else {
@@ -59,7 +64,7 @@
       this.proxy_ = null;
     }
     if (this.handle_) {
-      this.handle_.close();
+      core.close(this.handle_);
       this.handle_ = null;
     }
   };
@@ -77,12 +82,12 @@
     var result;
     if (this.router_) {
       // TODO(yzshen): Fix Router interface to support extracting handle.
-      result = new mojoBindings.InterfacePtrInfo(
+      result = new types.InterfacePtrInfo(
           this.router_.connector_.handle_, this.version);
       this.router_.connector_.handle_ = null;
     } else {
       // This also handles the case when this object is not bound.
-      result = new mojoBindings.InterfacePtrInfo(this.handle_, this.version);
+      result = new types.InterfacePtrInfo(this.handle_, this.version);
       this.handle_ = null;
     }
 
@@ -104,11 +109,12 @@
     if (!this.handle_)
       return;
 
-    this.router_ = new internal.Router(this.handle_);
+    this.router_ = new router.Router(this.handle_);
     this.handle_ = null;
     this.router_ .setPayloadValidators([this.interfaceType_.validateResponse]);
 
-    this.controlMessageProxy_ = new internal.ControlMessageProxy(this.router_);
+    this.controlMessageProxy_ = new
+        controlMessageProxy.ControlMessageProxy(this.router_);
 
     this.proxy_ = new this.interfaceType_.proxyClass(this.router_);
   };
@@ -173,13 +179,13 @@
   Binding.prototype.bind = function(requestOrHandle) {
     this.close();
 
-    var handle = requestOrHandle instanceof mojoBindings.InterfaceRequest ?
+    var handle = requestOrHandle instanceof types.InterfaceRequest ?
         requestOrHandle.handle : requestOrHandle;
-    if (!(handle instanceof MojoHandle))
+    if (!core.isHandle(handle))
       return;
 
     this.stub_ = new this.interfaceType_.stubClass(this.impl_);
-    this.router_ = new internal.Router(handle, this.interfaceType_.kVersion);
+    this.router_ = new router.Router(handle, this.interfaceType_.kVersion);
     this.router_.setIncomingReceiver(this.stub_);
     this.router_ .setPayloadValidators([this.interfaceType_.validateRequest]);
   };
@@ -202,10 +208,9 @@
 
   Binding.prototype.unbind = function() {
     if (!this.isBound())
-      return new mojoBindings.InterfaceRequest(null);
+      return new types.InterfaceRequest(null);
 
-    var result = new mojoBindings.InterfaceRequest(
-        this.router_.connector_.handle_);
+    var result = new types.InterfaceRequest(this.router_.connector_.handle_);
     this.router_.connector_.handle_ = null;
     this.close();
     return result;
@@ -268,9 +273,13 @@
       this.errorHandler_();
   };
 
+  var exports = {};
+  exports.InterfacePtrInfo = types.InterfacePtrInfo;
+  exports.InterfaceRequest = types.InterfaceRequest;
+  exports.makeRequest = makeRequest;
+  exports.InterfacePtrController = InterfacePtrController;
+  exports.Binding = Binding;
+  exports.BindingSet = BindingSet;
 
-  mojoBindings.makeRequest = makeRequest;
-  mojoBindings.Binding = Binding;
-  mojoBindings.BindingSet = BindingSet;
-  mojoBindings.InterfacePtrController = InterfacePtrController;
-})();
+  return exports;
+});
diff --git a/mojo/public/js/new_bindings/buffer.js b/mojo/public/js/new_bindings/buffer.js
index 7c0853c..e35f6951 100644
--- a/mojo/public/js/new_bindings/buffer.js
+++ b/mojo/public/js/new_bindings/buffer.js
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
-  var internal = mojoBindings.internal;
+define("mojo/public/js/buffer", function() {
 
   var kHostIsLittleEndian = (function () {
     var endianArrayBuffer = new ArrayBuffer(2);
@@ -151,5 +150,7 @@
     this.dataView.setFloat64(offset, value, kHostIsLittleEndian);
   }
 
-  internal.Buffer = Buffer;
-})();
+  var exports = {};
+  exports.Buffer = Buffer;
+  return exports;
+});
diff --git a/mojo/public/js/new_bindings/codec.js b/mojo/public/js/new_bindings/codec.js
index 5976e95..ff5d31a 100644
--- a/mojo/public/js/new_bindings/codec.js
+++ b/mojo/public/js/new_bindings/codec.js
@@ -2,8 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
-  var internal = mojoBindings.internal;
+define("mojo/public/js/codec", [
+  "mojo/public/js/buffer",
+  "mojo/public/js/interface_types",
+  "mojo/public/js/unicode",
+], function(buffer, types, unicode) {
 
   var kErrorUnsigned = "Passing negative value to unsigned";
   var kErrorArray = "Passing non Array for array type";
@@ -135,7 +138,7 @@
     var numberOfElements = this.readUint32();
     var base = this.next;
     this.next += numberOfElements;
-    return internal.decodeUtf8String(
+    return unicode.decodeUtf8String(
         new Uint8Array(this.buffer.arrayBuffer, base, numberOfElements));
   };
 
@@ -311,7 +314,7 @@
 
   Encoder.prototype.encodeString = function(val) {
     var base = this.next + kArrayHeaderSize;
-    var numberOfElements = internal.encodeUtf8String(
+    var numberOfElements = unicode.encodeUtf8String(
         val, new Uint8Array(this.buffer.arrayBuffer, base));
     var numberOfBytes = kArrayHeaderSize + numberOfElements;
     this.writeUint32(numberOfBytes);
@@ -386,7 +389,7 @@
     if (typeof(val) !== "string") {
       throw new Error(kErrorString);
     }
-    var encodedSize = kArrayHeaderSize + internal.utf8Length(val);
+    var encodedSize = kArrayHeaderSize + unicode.utf8Length(val);
     var encoder = this.createAndEncodeEncoder(encodedSize);
     encoder.encodeString(val);
   };
@@ -470,7 +473,7 @@
     // Currently, we don't compute the payload size correctly ahead of time.
     // Instead, we resize the buffer at the end.
     var numberOfBytes = kMessageHeaderSize + payloadSize;
-    this.buffer = new internal.Buffer(numberOfBytes);
+    this.buffer = new buffer.Buffer(numberOfBytes);
     this.handles = [];
     var encoder = this.createEncoder(kMessageHeaderSize);
     encoder.writeUint32(kMessageHeaderSize);
@@ -508,7 +511,7 @@
     // Currently, we don't compute the payload size correctly ahead of time.
     // Instead, we resize the buffer at the end.
     var numberOfBytes = kMessageWithRequestIDHeaderSize + payloadSize;
-    this.buffer = new internal.Buffer(numberOfBytes);
+    this.buffer = new buffer.Buffer(numberOfBytes);
     this.handles = [];
     var encoder = this.createEncoder(kMessageWithRequestIDHeaderSize);
     encoder.writeUint32(kMessageWithRequestIDHeaderSize);
@@ -811,7 +814,7 @@
   Interface.prototype.encodedSize = 8;
 
   Interface.prototype.decode = function(decoder) {
-    var interfacePtrInfo = new mojoBindings.InterfacePtrInfo(
+    var interfacePtrInfo = new types.InterfacePtrInfo(
         decoder.decodeHandle(), decoder.readUint32());
     var interfacePtr = new this.cls();
     interfacePtr.ptr.bind(interfacePtrInfo);
@@ -820,8 +823,7 @@
 
   Interface.prototype.encode = function(encoder, val) {
     var interfacePtrInfo =
-        val ? val.ptr.passInterface() :
-              new mojoBindings.InterfacePtrInfo(null, 0);
+        val ? val.ptr.passInterface() : new types.InterfacePtrInfo(null, 0);
     encoder.encodeHandle(interfacePtrInfo.handle);
     encoder.writeUint32(interfacePtrInfo.version);
   };
@@ -838,7 +840,7 @@
   InterfaceRequest.encodedSize = 4;
 
   InterfaceRequest.decode = function(decoder) {
-    return new mojoBindings.InterfaceRequest(decoder.decodeHandle());
+    return new types.InterfaceRequest(decoder.decodeHandle());
   };
 
   InterfaceRequest.encode = function(encoder, val) {
@@ -875,44 +877,46 @@
 
   NullableMapOf.prototype = Object.create(MapOf.prototype);
 
-  internal.align = align;
-  internal.isAligned = isAligned;
-  internal.Message = Message;
-  internal.MessageBuilder = MessageBuilder;
-  internal.MessageWithRequestIDBuilder = MessageWithRequestIDBuilder;
-  internal.MessageReader = MessageReader;
-  internal.kArrayHeaderSize = kArrayHeaderSize;
-  internal.kMapStructPayloadSize = kMapStructPayloadSize;
-  internal.kStructHeaderSize = kStructHeaderSize;
-  internal.kEncodedInvalidHandleValue = kEncodedInvalidHandleValue;
-  internal.kMessageHeaderSize = kMessageHeaderSize;
-  internal.kMessageWithRequestIDHeaderSize = kMessageWithRequestIDHeaderSize;
-  internal.kMessageExpectsResponse = kMessageExpectsResponse;
-  internal.kMessageIsResponse = kMessageIsResponse;
-  internal.Int8 = Int8;
-  internal.Uint8 = Uint8;
-  internal.Int16 = Int16;
-  internal.Uint16 = Uint16;
-  internal.Int32 = Int32;
-  internal.Uint32 = Uint32;
-  internal.Int64 = Int64;
-  internal.Uint64 = Uint64;
-  internal.Float = Float;
-  internal.Double = Double;
-  internal.String = String;
-  internal.Enum = Enum;
-  internal.NullableString = NullableString;
-  internal.PointerTo = PointerTo;
-  internal.NullablePointerTo = NullablePointerTo;
-  internal.ArrayOf = ArrayOf;
-  internal.NullableArrayOf = NullableArrayOf;
-  internal.PackedBool = PackedBool;
-  internal.Handle = Handle;
-  internal.NullableHandle = NullableHandle;
-  internal.Interface = Interface;
-  internal.NullableInterface = NullableInterface;
-  internal.InterfaceRequest = InterfaceRequest;
-  internal.NullableInterfaceRequest = NullableInterfaceRequest;
-  internal.MapOf = MapOf;
-  internal.NullableMapOf = NullableMapOf;
-})();
+  var exports = {};
+  exports.align = align;
+  exports.isAligned = isAligned;
+  exports.Message = Message;
+  exports.MessageBuilder = MessageBuilder;
+  exports.MessageWithRequestIDBuilder = MessageWithRequestIDBuilder;
+  exports.MessageReader = MessageReader;
+  exports.kArrayHeaderSize = kArrayHeaderSize;
+  exports.kMapStructPayloadSize = kMapStructPayloadSize;
+  exports.kStructHeaderSize = kStructHeaderSize;
+  exports.kEncodedInvalidHandleValue = kEncodedInvalidHandleValue;
+  exports.kMessageHeaderSize = kMessageHeaderSize;
+  exports.kMessageWithRequestIDHeaderSize = kMessageWithRequestIDHeaderSize;
+  exports.kMessageExpectsResponse = kMessageExpectsResponse;
+  exports.kMessageIsResponse = kMessageIsResponse;
+  exports.Int8 = Int8;
+  exports.Uint8 = Uint8;
+  exports.Int16 = Int16;
+  exports.Uint16 = Uint16;
+  exports.Int32 = Int32;
+  exports.Uint32 = Uint32;
+  exports.Int64 = Int64;
+  exports.Uint64 = Uint64;
+  exports.Float = Float;
+  exports.Double = Double;
+  exports.String = String;
+  exports.Enum = Enum;
+  exports.NullableString = NullableString;
+  exports.PointerTo = PointerTo;
+  exports.NullablePointerTo = NullablePointerTo;
+  exports.ArrayOf = ArrayOf;
+  exports.NullableArrayOf = NullableArrayOf;
+  exports.PackedBool = PackedBool;
+  exports.Handle = Handle;
+  exports.NullableHandle = NullableHandle;
+  exports.Interface = Interface;
+  exports.NullableInterface = NullableInterface;
+  exports.InterfaceRequest = InterfaceRequest;
+  exports.NullableInterfaceRequest = NullableInterfaceRequest;
+  exports.MapOf = MapOf;
+  exports.NullableMapOf = NullableMapOf;
+  return exports;
+});
diff --git a/mojo/public/js/new_bindings/connector.js b/mojo/public/js/new_bindings/connector.js
index 3f1bf98..4d062786 100644
--- a/mojo/public/js/new_bindings/connector.js
+++ b/mojo/public/js/new_bindings/connector.js
@@ -2,11 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
-  var internal = mojoBindings.internal;
+define("mojo/public/js/connector", [
+  "mojo/public/js/buffer",
+  "mojo/public/js/codec",
+  "mojo/public/js/core",
+  "mojo/public/js/support",
+], function(buffer, codec, core, support) {
 
   function Connector(handle) {
-    if (!(handle instanceof MojoHandle))
+    if (!core.isHandle(handle))
       throw new Error("Connector: not a handle " + handle);
     this.handle_ = handle;
     this.dropWrites_ = false;
@@ -16,18 +20,19 @@
     this.errorHandler_ = null;
 
     if (handle) {
-      this.readWatcher_ = handle.watch({readable: true},
-                                       this.readMore_.bind(this));
+      this.readWatcher_ = support.watch(handle,
+                                        core.HANDLE_SIGNAL_READABLE,
+                                        this.readMore_.bind(this));
     }
   }
 
   Connector.prototype.close = function() {
     if (this.readWatcher_) {
-      this.readWatcher_.cancel();
+      support.cancelWatch(this.readWatcher_);
       this.readWatcher_ = null;
     }
     if (this.handle_ != null) {
-      this.handle_.close();
+      core.close(this.handle_);
       this.handle_ = null;
     }
   };
@@ -39,15 +44,17 @@
     if (this.dropWrites_)
       return true;
 
-    var result = this.handle_.writeMessage(
-        new Uint8Array(message.buffer.arrayBuffer), message.handles);
+    var result = core.writeMessage(this.handle_,
+                                   new Uint8Array(message.buffer.arrayBuffer),
+                                   message.handles,
+                                   core.WRITE_MESSAGE_FLAG_NONE);
     switch (result) {
-      case Mojo.RESULT_OK:
+      case core.RESULT_OK:
         // The handles were successfully transferred, so we don't own them
         // anymore.
         message.handles = [];
         break;
-      case Mojo.RESULT_FAILED_PRECONDITION:
+      case core.RESULT_FAILED_PRECONDITION:
         // There's no point in continuing to write to this pipe since the other
         // end is gone. Avoid writing any future messages. Hide write failures
         // from the caller since we'd like them to continue consuming any
@@ -76,29 +83,32 @@
   };
 
   Connector.prototype.waitForNextMessageForTesting = function() {
-    // TODO(yzshen): Change the tests that use this method.
-    throw new Error("Not supported!");
+    var wait = core.wait(this.handle_, core.HANDLE_SIGNAL_READABLE);
+    this.readMore_(wait.result);
   };
 
   Connector.prototype.readMore_ = function(result) {
     for (;;) {
-      var read = this.handle_.readMessage();
+      var read = core.readMessage(this.handle_,
+                                  core.READ_MESSAGE_FLAG_NONE);
       if (this.handle_ == null) // The connector has been closed.
         return;
-      if (read.result == Mojo.RESULT_SHOULD_WAIT)
+      if (read.result == core.RESULT_SHOULD_WAIT)
         return;
-      if (read.result != Mojo.RESULT_OK) {
+      if (read.result != core.RESULT_OK) {
         this.error_ = true;
         if (this.errorHandler_)
           this.errorHandler_.onError(read.result);
         return;
       }
-      var messageBuffer = new internal.Buffer(read.buffer);
-      var message = new internal.Message(messageBuffer, read.handles);
+      var messageBuffer = new buffer.Buffer(read.buffer);
+      var message = new codec.Message(messageBuffer, read.handles);
       if (this.incomingReceiver_)
         this.incomingReceiver_.accept(message);
     }
   };
 
-  internal.Connector = Connector;
-})();
+  var exports = {};
+  exports.Connector = Connector;
+  return exports;
+});
diff --git a/mojo/public/js/new_bindings/interface_types.js b/mojo/public/js/new_bindings/interface_types.js
index f82789d2..01ea2d1 100644
--- a/mojo/public/js/new_bindings/interface_types.js
+++ b/mojo/public/js/new_bindings/interface_types.js
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
+define("mojo/public/js/interface_types", [
+  "mojo/public/js/core",
+], function(core) {
+
   // ---------------------------------------------------------------------------
 
   function InterfacePtrInfo(handle, version) {
@@ -11,14 +14,14 @@
   }
 
   InterfacePtrInfo.prototype.isValid = function() {
-    return this.handle instanceof MojoHandle;
+    return core.isHandle(this.handle);
   };
 
   InterfacePtrInfo.prototype.close = function() {
     if (!this.isValid())
       return;
 
-    this.handle.close();
+    core.close(this.handle);
     this.handle = null;
     this.version = 0;
   };
@@ -30,17 +33,20 @@
   }
 
   InterfaceRequest.prototype.isValid = function() {
-    return this.handle instanceof MojoHandle;
+    return core.isHandle(this.handle);
   };
 
   InterfaceRequest.prototype.close = function() {
     if (!this.isValid())
       return;
 
-    this.handle.close();
+    core.close(this.handle);
     this.handle = null;
   };
 
-  mojoBindings.InterfacePtrInfo = InterfacePtrInfo;
-  mojoBindings.InterfaceRequest = InterfaceRequest;
-})();
+  var exports = {};
+  exports.InterfacePtrInfo = InterfacePtrInfo;
+  exports.InterfaceRequest = InterfaceRequest;
+
+  return exports;
+});
diff --git a/mojo/public/js/new_bindings/lib/control_message_handler.js b/mojo/public/js/new_bindings/lib/control_message_handler.js
index bbd526ea..81d9002 100644
--- a/mojo/public/js/new_bindings/lib/control_message_handler.js
+++ b/mojo/public/js/new_bindings/lib/control_message_handler.js
@@ -2,88 +2,90 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
-  var internal = mojoBindings.internal;
+define("mojo/public/js/lib/control_message_handler", [
+  "mojo/public/js/codec",
+  "mojo/public/interfaces/bindings/interface_control_messages.mojom",
+  "mojo/public/js/validator",
+], function(codec, controlMessages, validator) {
+
+  var Validator = validator.Validator;
 
   function validateControlRequestWithResponse(message) {
-    var messageValidator = new internal.Validator(message);
+    var messageValidator = new Validator(message);
     var error = messageValidator.validateMessageIsRequestExpectingResponse();
-    if (error !== internal.validationError.NONE) {
+    if (error !== validator.validationError.NONE) {
       throw error;
     }
 
-    if (message.getName() != mojo.interface_control2.kRunMessageId) {
+    if (message.getName() != controlMessages.kRunMessageId) {
       throw new Error("Control message name is not kRunMessageId");
     }
 
     // Validate payload.
-    error = mojo.interface_control2.RunMessageParams.validate(messageValidator,
+    error = controlMessages.RunMessageParams.validate(messageValidator,
         message.getHeaderNumBytes());
-    if (error != internal.validationError.NONE) {
+    if (error != validator.validationError.NONE) {
       throw error;
     }
   }
 
   function validateControlRequestWithoutResponse(message) {
-    var messageValidator = new internal.Validator(message);
+    var messageValidator = new Validator(message);
     var error = messageValidator.validateMessageIsRequestWithoutResponse();
-    if (error != internal.validationError.NONE) {
+    if (error != validator.validationError.NONE) {
       throw error;
     }
 
-    if (message.getName() != mojo.interface_control2.kRunOrClosePipeMessageId) {
+    if (message.getName() != controlMessages.kRunOrClosePipeMessageId) {
       throw new Error("Control message name is not kRunOrClosePipeMessageId");
     }
 
     // Validate payload.
-    error = mojo.interface_control2.RunOrClosePipeMessageParams.validate(
+    error = controlMessages.RunOrClosePipeMessageParams.validate(
         messageValidator, message.getHeaderNumBytes());
-    if (error != internal.validationError.NONE) {
+    if (error != validator.validationError.NONE) {
       throw error;
     }
   }
 
   function runOrClosePipe(message, interface_version) {
-    var reader = new internal.MessageReader(message);
+    var reader = new codec.MessageReader(message);
     var runOrClosePipeMessageParams = reader.decodeStruct(
-        mojo.interface_control2.RunOrClosePipeMessageParams);
+        controlMessages.RunOrClosePipeMessageParams);
     return interface_version >=
         runOrClosePipeMessageParams.input.require_version.version;
   }
 
   function run(message, responder, interface_version) {
-    var reader = new internal.MessageReader(message);
+    var reader = new codec.MessageReader(message);
     var runMessageParams =
-        reader.decodeStruct(mojo.interface_control2.RunMessageParams);
+        reader.decodeStruct(controlMessages.RunMessageParams);
     var runOutput = null;
 
     if (runMessageParams.input.query_version) {
-      runOutput = new mojo.interface_control2.RunOutput();
+      runOutput = new controlMessages.RunOutput();
       runOutput.query_version_result = new
-          mojo.interface_control2.QueryVersionResult(
-              {'version': interface_version});
+          controlMessages.QueryVersionResult({'version': interface_version});
     }
 
     var runResponseMessageParams = new
-        mojo.interface_control2.RunResponseMessageParams();
+        controlMessages.RunResponseMessageParams();
     runResponseMessageParams.output = runOutput;
 
-    var messageName = mojo.interface_control2.kRunMessageId;
-    var payloadSize =
-        mojo.interface_control2.RunResponseMessageParams.encodedSize;
+    var messageName = controlMessages.kRunMessageId;
+    var payloadSize = controlMessages.RunResponseMessageParams.encodedSize;
     var requestID = reader.requestID;
-    var builder = new internal.MessageWithRequestIDBuilder(messageName,
-        payloadSize, internal.kMessageIsResponse, requestID);
-    builder.encodeStruct(mojo.interface_control2.RunResponseMessageParams,
+    var builder = new codec.MessageWithRequestIDBuilder(messageName,
+        payloadSize, codec.kMessageIsResponse, requestID);
+    builder.encodeStruct(controlMessages.RunResponseMessageParams,
                          runResponseMessageParams);
     responder.accept(builder.finish());
     return true;
   }
 
-  function isInterfaceControlMessage(message) {
-    return message.getName() == mojo.interface_control2.kRunMessageId ||
-           message.getName() ==
-               mojo.interface_control2.kRunOrClosePipeMessageId;
+  function isControlMessage(message) {
+    return message.getName() == controlMessages.kRunMessageId ||
+           message.getName() == controlMessages.kRunOrClosePipeMessageId;
   }
 
   function ControlMessageHandler(interface_version) {
@@ -101,6 +103,9 @@
     return run(message, responder, this.interface_version);
   };
 
-  internal.ControlMessageHandler = ControlMessageHandler;
-  internal.isInterfaceControlMessage = isInterfaceControlMessage;
-})();
+  var exports = {};
+  exports.ControlMessageHandler = ControlMessageHandler;
+  exports.isControlMessage = isControlMessage;
+
+  return exports;
+});
diff --git a/mojo/public/js/new_bindings/lib/control_message_proxy.js b/mojo/public/js/new_bindings/lib/control_message_proxy.js
index 53aa34d..d6c0734f 100644
--- a/mojo/public/js/new_bindings/lib/control_message_proxy.js
+++ b/mojo/public/js/new_bindings/lib/control_message_proxy.js
@@ -2,35 +2,39 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
-  var internal = mojoBindings.internal;
+define("mojo/public/js/lib/control_message_proxy", [
+  "mojo/public/interfaces/bindings/interface_control_messages.mojom",
+  "mojo/public/js/codec",
+  "mojo/public/js/validator",
+], function(controlMessages, codec, validator) {
+
+  var Validator = validator.Validator;
 
   function sendRunOrClosePipeMessage(receiver, runOrClosePipeMessageParams) {
-    var messageName = mojo.interface_control2.kRunOrClosePipeMessageId;
-    var payloadSize =
-        mojo.interface_control2.RunOrClosePipeMessageParams.encodedSize;
-    var builder = new internal.MessageBuilder(messageName, payloadSize);
-    builder.encodeStruct(mojo.interface_control2.RunOrClosePipeMessageParams,
+    var messageName = controlMessages.kRunOrClosePipeMessageId;
+    var payloadSize = controlMessages.RunOrClosePipeMessageParams.encodedSize;
+    var builder = new codec.MessageBuilder(messageName, payloadSize);
+    builder.encodeStruct(controlMessages.RunOrClosePipeMessageParams,
                          runOrClosePipeMessageParams);
     var message = builder.finish();
     receiver.accept(message);
   }
 
   function validateControlResponse(message) {
-    var messageValidator = new internal.Validator(message);
+    var messageValidator = new Validator(message);
     var error = messageValidator.validateMessageIsResponse();
-    if (error != internal.validationError.NONE) {
+    if (error != validator.validationError.NONE) {
       throw error;
     }
 
-    if (message.getName() != mojo.interface_control2.kRunMessageId) {
+    if (message.getName() != controlMessages.kRunMessageId) {
       throw new Error("Control message name is not kRunMessageId");
     }
 
     // Validate payload.
-    error = mojo.interface_control2.RunResponseMessageParams.validate(
+    error = controlMessages.RunResponseMessageParams.validate(
         messageValidator, message.getHeaderNumBytes());
-    if (error != internal.validationError.NONE) {
+    if (error != validator.validationError.NONE) {
       throw error;
     }
   }
@@ -38,9 +42,9 @@
   function acceptRunResponse(message) {
     validateControlResponse(message);
 
-    var reader = new internal.MessageReader(message);
+    var reader = new codec.MessageReader(message);
     var runResponseMessageParams = reader.decodeStruct(
-        mojo.interface_control2.RunResponseMessageParams);
+        controlMessages.RunResponseMessageParams);
 
     return Promise.resolve(runResponseMessageParams);
   }
@@ -55,13 +59,12 @@
   * @return {Promise} that resolves to a RunResponseMessageParams.
   */
   function sendRunMessage(receiver, runMessageParams) {
-    var messageName = mojo.interface_control2.kRunMessageId;
-    var payloadSize = mojo.interface_control2.RunMessageParams.encodedSize;
+    var messageName = controlMessages.kRunMessageId;
+    var payloadSize = controlMessages.RunMessageParams.encodedSize;
     // |requestID| is set to 0, but is later properly set by Router.
-    var builder = new internal.MessageWithRequestIDBuilder(messageName,
-        payloadSize, internal.kMessageExpectsResponse, 0);
-    builder.encodeStruct(mojo.interface_control2.RunMessageParams,
-                         runMessageParams);
+    var builder = new codec.MessageWithRequestIDBuilder(messageName,
+        payloadSize, codec.kMessageExpectsResponse, 0);
+    builder.encodeStruct(controlMessages.RunMessageParams, runMessageParams);
     var message = builder.finish();
 
     return receiver.acceptAndExpectResponse(message).then(acceptRunResponse);
@@ -72,10 +75,9 @@
   }
 
   ControlMessageProxy.prototype.queryVersion = function() {
-    var runMessageParams = new mojo.interface_control2.RunMessageParams();
-    runMessageParams.input = new mojo.interface_control2.RunInput();
-    runMessageParams.input.query_version =
-        new mojo.interface_control2.QueryVersion();
+    var runMessageParams = new controlMessages.RunMessageParams();
+    runMessageParams.input = new controlMessages.RunInput();
+    runMessageParams.input.query_version = new controlMessages.QueryVersion();
 
     return sendRunMessage(this.receiver, runMessageParams).then(function(
         runResponseMessageParams) {
@@ -85,13 +87,16 @@
 
   ControlMessageProxy.prototype.requireVersion = function(version) {
     var runOrClosePipeMessageParams = new
-        mojo.interface_control2.RunOrClosePipeMessageParams();
+        controlMessages.RunOrClosePipeMessageParams();
     runOrClosePipeMessageParams.input = new
-        mojo.interface_control2.RunOrClosePipeInput();
+        controlMessages.RunOrClosePipeInput();
     runOrClosePipeMessageParams.input.require_version = new
-        mojo.interface_control2.RequireVersion({'version': version});
+        controlMessages.RequireVersion({'version': version});
     sendRunOrClosePipeMessage(this.receiver, runOrClosePipeMessageParams);
   };
 
-  internal.ControlMessageProxy = ControlMessageProxy;
-})();
+  var exports = {};
+  exports.ControlMessageProxy = ControlMessageProxy;
+
+  return exports;
+});
diff --git a/mojo/public/js/new_bindings/router.js b/mojo/public/js/new_bindings/router.js
index 61b3395..e94c5eb 100644
--- a/mojo/public/js/new_bindings/router.js
+++ b/mojo/public/js/new_bindings/router.js
@@ -2,14 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
-  var internal = mojoBindings.internal;
+define("mojo/public/js/router", [
+  "console",
+  "mojo/public/js/codec",
+  "mojo/public/js/core",
+  "mojo/public/js/connector",
+  "mojo/public/js/lib/control_message_handler",
+  "mojo/public/js/validator",
+], function(console, codec, core, connector, controlMessageHandler, validator) {
+
+  var Connector = connector.Connector;
+  var MessageReader = codec.MessageReader;
+  var Validator = validator.Validator;
+  var ControlMessageHandler = controlMessageHandler.ControlMessageHandler;
 
   function Router(handle, interface_version, connectorFactory) {
-    if (!(handle instanceof MojoHandle))
+    if (!core.isHandle(handle))
       throw new Error("Router constructor: Not a handle");
     if (connectorFactory === undefined)
-      connectorFactory = internal.Connector;
+      connectorFactory = Connector;
     this.connector_ = new connectorFactory(handle);
     this.incomingReceiver_ = null;
     this.errorHandler_ = null;
@@ -20,7 +31,7 @@
 
     if (interface_version !== undefined) {
       this.controlMessageHandler_ = new
-          internal.ControlMessageHandler(interface_version);
+          ControlMessageHandler(interface_version);
     }
 
     this.connector_.setIncomingReceiver({
@@ -86,8 +97,8 @@
   };
 
   Router.prototype.handleIncomingMessage_ = function(message) {
-    var noError = internal.validationError.NONE;
-    var messageValidator = new internal.Validator(message);
+    var noError = validator.validationError.NONE;
+    var messageValidator = new Validator(message);
     var err = messageValidator.validateMessageHeader();
     for (var i = 0; err === noError && i < this.payloadValidators_.length; ++i)
       err = this.payloadValidators_[i](messageValidator);
@@ -103,7 +114,7 @@
       return;
 
     if (message.expectsResponse()) {
-      if (internal.isInterfaceControlMessage(message)) {
+      if (controlMessageHandler.isControlMessage(message)) {
         if (this.controlMessageHandler_) {
           this.controlMessageHandler_.acceptWithResponder(message, this);
         } else {
@@ -117,7 +128,7 @@
         this.close();
       }
     } else if (message.isResponse()) {
-      var reader = new internal.MessageReader(message);
+      var reader = new MessageReader(message);
       var requestID = reader.requestID;
       var completer = this.completers_.get(requestID);
       if (completer) {
@@ -127,7 +138,7 @@
         console.log("Unexpected response with request ID: " + requestID);
       }
     } else {
-      if (internal.isInterfaceControlMessage(message)) {
+      if (controlMessageHandler.isControlMessage(message)) {
         if (this.controlMessageHandler_) {
           var ok = this.controlMessageHandler_.accept(message);
           if (ok) return;
@@ -145,7 +156,7 @@
       // TODO(yzshen): This should also trigger connection error handler.
       // Consider making accept() return a boolean and let the connector deal
       // with this, as the C++ code does.
-      console.log("Invalid message: " + internal.validationError[error]);
+      console.log("Invalid message: " + validator.validationError[error]);
 
       this.close();
       return;
@@ -186,5 +197,7 @@
       this.invalidMessageHandler_(error);
   };
 
-  internal.Router = Router;
-})();
+  var exports = {};
+  exports.Router = Router;
+  return exports;
+});
diff --git a/mojo/public/js/new_bindings/unicode.js b/mojo/public/js/new_bindings/unicode.js
index a3c0df7..be2ba0e 100644
--- a/mojo/public/js/new_bindings/unicode.js
+++ b/mojo/public/js/new_bindings/unicode.js
@@ -7,9 +7,7 @@
  * stored in ArrayBuffers. There is much room for optimization in this code if
  * it proves necessary.
  */
-(function() {
-  var internal = mojoBindings.internal;
-
+define("mojo/public/js/unicode", function() {
   /**
    * Decodes the UTF8 string from the given buffer.
    * @param {ArrayBufferView} buffer The buffer containing UTF8 string data.
@@ -45,7 +43,9 @@
     return utf8String.length;
   }
 
-  internal.decodeUtf8String = decodeUtf8String;
-  internal.encodeUtf8String = encodeUtf8String;
-  internal.utf8Length = utf8Length;
-})();
+  var exports = {};
+  exports.decodeUtf8String = decodeUtf8String;
+  exports.encodeUtf8String = encodeUtf8String;
+  exports.utf8Length = utf8Length;
+  return exports;
+});
diff --git a/mojo/public/js/new_bindings/validator.js b/mojo/public/js/new_bindings/validator.js
index e960552..fee742d0 100644
--- a/mojo/public/js/new_bindings/validator.js
+++ b/mojo/public/js/new_bindings/validator.js
@@ -2,8 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
-  var internal = mojoBindings.internal;
+define("mojo/public/js/validator", [
+  "mojo/public/js/codec",
+], function(codec) {
 
   var validationError = {
     NONE: 'VALIDATION_ERROR_NONE',
@@ -29,33 +30,32 @@
   var NULL_MOJO_POINTER = "NULL_MOJO_POINTER";
 
   function isEnumClass(cls) {
-    return cls instanceof internal.Enum;
+    return cls instanceof codec.Enum;
   }
 
   function isStringClass(cls) {
-    return cls === internal.String || cls === internal.NullableString;
+    return cls === codec.String || cls === codec.NullableString;
   }
 
   function isHandleClass(cls) {
-    return cls === internal.Handle || cls === internal.NullableHandle;
+    return cls === codec.Handle || cls === codec.NullableHandle;
   }
 
   function isInterfaceClass(cls) {
-    return cls instanceof internal.Interface;
+    return cls instanceof codec.Interface;
   }
 
   function isInterfaceRequestClass(cls) {
-    return cls === internal.InterfaceRequest ||
-        cls === internal.NullableInterfaceRequest;
+    return cls === codec.InterfaceRequest ||
+        cls === codec.NullableInterfaceRequest;
   }
 
   function isNullable(type) {
-    return type === internal.NullableString ||
-        type === internal.NullableHandle ||
-        type === internal.NullableInterface ||
-        type === internal.NullableInterfaceRequest ||
-        type instanceof internal.NullableArrayOf ||
-        type instanceof internal.NullablePointerTo;
+    return type === codec.NullableString || type === codec.NullableHandle ||
+        type === codec.NullableInterface ||
+        type === codec.NullableInterfaceRequest ||
+        type instanceof codec.NullableArrayOf ||
+        type instanceof codec.NullablePointerTo;
   }
 
   function Validator(message) {
@@ -98,7 +98,7 @@
   };
 
   Validator.prototype.claimHandle = function(index) {
-    if (index === internal.kEncodedInvalidHandleValue)
+    if (index === codec.kEncodedInvalidHandleValue)
       return true;
 
     if (index < this.handleIndex || index >= this.handleIndexLimit)
@@ -119,7 +119,7 @@
   Validator.prototype.validateHandle = function(offset, nullable) {
     var index = this.message.buffer.getUint32(offset);
 
-    if (index === internal.kEncodedInvalidHandleValue)
+    if (index === codec.kEncodedInvalidHandleValue)
       return nullable ?
           validationError.NONE : validationError.UNEXPECTED_INVALID_HANDLE;
 
@@ -138,10 +138,10 @@
   };
 
   Validator.prototype.validateStructHeader = function(offset, minNumBytes) {
-    if (!internal.isAligned(offset))
+    if (!codec.isAligned(offset))
       return validationError.MISALIGNED_OBJECT;
 
-    if (!this.isValidRange(offset, internal.kStructHeaderSize))
+    if (!this.isValidRange(offset, codec.kStructHeaderSize))
       return validationError.ILLEGAL_MEMORY_RANGE;
 
     var numBytes = this.message.buffer.getUint32(offset);
@@ -182,7 +182,7 @@
 
   Validator.prototype.validateMessageHeader = function() {
 
-    var err = this.validateStructHeader(0, internal.kMessageHeaderSize);
+    var err = this.validateStructHeader(0, codec.kMessageHeaderSize);
     if (err != validationError.NONE)
       return err;
 
@@ -190,11 +190,11 @@
     var version = this.message.getHeaderVersion();
 
     var validVersionAndNumBytes =
-        (version == 0 && numBytes == internal.kMessageHeaderSize) ||
+        (version == 0 && numBytes == codec.kMessageHeaderSize) ||
         (version == 1 &&
-         numBytes == internal.kMessageWithRequestIDHeaderSize) ||
+         numBytes == codec.kMessageWithRequestIDHeaderSize) ||
         (version > 1 &&
-         numBytes >= internal.kMessageWithRequestIDHeaderSize);
+         numBytes >= codec.kMessageWithRequestIDHeaderSize);
     if (!validVersionAndNumBytes)
       return validationError.UNEXPECTED_STRUCT_HEADER;
 
@@ -322,14 +322,13 @@
       return mapIsNullable ?
           validationError.NONE : validationError.UNEXPECTED_NULL_POINTER;
 
-    var mapEncodedSize = internal.kStructHeaderSize +
-        internal.kMapStructPayloadSize;
+    var mapEncodedSize = codec.kStructHeaderSize + codec.kMapStructPayloadSize;
     var err = this.validateStructHeader(structOffset, mapEncodedSize);
     if (err !== validationError.NONE)
         return err;
 
     // Validate the keys array.
-    var keysArrayPointerOffset = structOffset + internal.kStructHeaderSize;
+    var keysArrayPointerOffset = structOffset + codec.kStructHeaderSize;
     err = this.validateArrayPointer(
         keysArrayPointerOffset, keyClass.encodedSize, keyClass, false, [0], 0);
     if (err !== validationError.NONE)
@@ -338,7 +337,7 @@
     // Validate the values array.
     var valuesArrayPointerOffset = keysArrayPointerOffset + 8;
     var valuesArrayDimensions = [0]; // Validate the actual length below.
-    if (valueClass instanceof internal.ArrayOf)
+    if (valueClass instanceof codec.ArrayOf)
       valuesArrayDimensions =
           valuesArrayDimensions.concat(valueClass.dimensions());
     var err = this.validateArrayPointer(valuesArrayPointerOffset,
@@ -361,7 +360,7 @@
 
   Validator.prototype.validateStringPointer = function(offset, nullable) {
     return this.validateArrayPointer(
-        offset, internal.Uint8.encodedSize, internal.Uint8, nullable, [0], 0);
+        offset, codec.Uint8.encodedSize, codec.Uint8, nullable, [0], 0);
   };
 
   // Similar to Array_Data<T>::Validate()
@@ -370,10 +369,10 @@
   Validator.prototype.validateArray =
       function (offset, elementSize, elementType, expectedDimensionSizes,
                 currentDimension) {
-    if (!internal.isAligned(offset))
+    if (!codec.isAligned(offset))
       return validationError.MISALIGNED_OBJECT;
 
-    if (!this.isValidRange(offset, internal.kArrayHeaderSize))
+    if (!this.isValidRange(offset, codec.kArrayHeaderSize))
       return validationError.ILLEGAL_MEMORY_RANGE;
 
     var numBytes = this.message.buffer.getUint32(offset);
@@ -381,10 +380,10 @@
 
     // Note: this computation is "safe" because elementSize <= 8 and
     // numElements is a uint32.
-    var elementsTotalSize = (elementType === internal.PackedBool) ?
+    var elementsTotalSize = (elementType === codec.PackedBool) ?
         Math.ceil(numElements / 8) : (elementSize * numElements);
 
-    if (numBytes < internal.kArrayHeaderSize + elementsTotalSize)
+    if (numBytes < codec.kArrayHeaderSize + elementsTotalSize)
       return validationError.UNEXPECTED_ARRAY_HEADER;
 
     if (expectedDimensionSizes[currentDimension] != 0 &&
@@ -397,7 +396,7 @@
 
     // Validate the array's elements if they are pointers or handles.
 
-    var elementsOffset = offset + internal.kArrayHeaderSize;
+    var elementsOffset = offset + codec.kArrayHeaderSize;
     var nullable = isNullable(elementType);
 
     if (isHandleClass(elementType))
@@ -410,11 +409,11 @@
           elementsOffset, numElements, nullable);
     if (isStringClass(elementType))
       return this.validateArrayElements(
-          elementsOffset, numElements, internal.Uint8, nullable, [0], 0);
-    if (elementType instanceof internal.PointerTo)
+          elementsOffset, numElements, codec.Uint8, nullable, [0], 0);
+    if (elementType instanceof codec.PointerTo)
       return this.validateStructElements(
           elementsOffset, numElements, elementType.cls, nullable);
-    if (elementType instanceof internal.ArrayOf)
+    if (elementType instanceof codec.ArrayOf)
       return this.validateArrayElements(
           elementsOffset, numElements, elementType.cls, nullable,
           expectedDimensionSizes, currentDimension + 1);
@@ -431,7 +430,7 @@
 
   Validator.prototype.validateHandleElements =
       function(offset, numElements, nullable) {
-    var elementSize = internal.Handle.encodedSize;
+    var elementSize = codec.Handle.encodedSize;
     for (var i = 0; i < numElements; i++) {
       var elementOffset = offset + i * elementSize;
       var err = this.validateHandle(elementOffset, nullable);
@@ -443,7 +442,7 @@
 
   Validator.prototype.validateInterfaceElements =
       function(offset, numElements, nullable) {
-    var elementSize = internal.Interface.prototype.encodedSize;
+    var elementSize = codec.Interface.prototype.encodedSize;
     for (var i = 0; i < numElements; i++) {
       var elementOffset = offset + i * elementSize;
       var err = this.validateInterface(elementOffset, nullable);
@@ -455,7 +454,7 @@
 
   Validator.prototype.validateInterfaceRequestElements =
       function(offset, numElements, nullable) {
-    var elementSize = internal.InterfaceRequest.encodedSize;
+    var elementSize = codec.InterfaceRequest.encodedSize;
     for (var i = 0; i < numElements; i++) {
       var elementOffset = offset + i * elementSize;
       var err = this.validateInterfaceRequest(elementOffset, nullable);
@@ -469,7 +468,7 @@
   Validator.prototype.validateArrayElements =
       function(offset, numElements, elementClass, nullable,
                expectedDimensionSizes, currentDimension) {
-    var elementSize = internal.PointerTo.prototype.encodedSize;
+    var elementSize = codec.PointerTo.prototype.encodedSize;
     for (var i = 0; i < numElements; i++) {
       var elementOffset = offset + i * elementSize;
       var err = this.validateArrayPointer(
@@ -483,7 +482,7 @@
 
   Validator.prototype.validateStructElements =
       function(offset, numElements, structClass, nullable) {
-    var elementSize = internal.PointerTo.prototype.encodedSize;
+    var elementSize = codec.PointerTo.prototype.encodedSize;
     for (var i = 0; i < numElements; i++) {
       var elementOffset = offset + i * elementSize;
       var err =
@@ -496,7 +495,7 @@
 
   Validator.prototype.validateEnumElements =
       function(offset, numElements, enumClass) {
-    var elementSize = internal.Enum.prototype.encodedSize;
+    var elementSize = codec.Enum.prototype.encodedSize;
     for (var i = 0; i < numElements; i++) {
       var elementOffset = offset + i * elementSize;
       var err = this.validateEnum(elementOffset, enumClass);
@@ -506,6 +505,8 @@
     return validationError.NONE;
   };
 
-  internal.validationError = validationError;
-  internal.Validator = Validator;
-})();
+  var exports = {};
+  exports.validationError = validationError;
+  exports.Validator = Validator;
+  return exports;
+});
diff --git a/mojo/public/tools/bindings/generators/js_templates/module.amd.tmpl b/mojo/public/tools/bindings/generators/js_templates/module.amd.tmpl
index cf349765..3ce4ab6 100644
--- a/mojo/public/tools/bindings/generators/js_templates/module.amd.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/module.amd.tmpl
@@ -2,47 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-{%- if use_new_js_bindings %}
-
-"use strict";
-
-(function() {
-  // TODO(yzshen): Define these aliases to minimize the differences between the
-  // old/new modes. Remove them when the old mode goes away.
-  var bindings = mojoBindings;
-  var codec = mojoBindings.internal;
-  var validator = mojoBindings.internal;
-{%-   for import in imports %}
-  var {{import.unique_name}} = {{import.module.namespace}};
-{%-   endfor %}
-
-{% include "module_definition.tmpl" %}
-})();
-
-{%- else %}
-
 define("{{module.path}}", [
-{%-   if module.path != "mojo/public/interfaces/bindings/interface_control_messages.mojom" %}
+{%- if module.path != "mojo/public/interfaces/bindings/interface_control_messages.mojom" %}
     "mojo/public/js/bindings",
-{%-   endif %}
+{%- endif %}
     "mojo/public/js/codec",
     "mojo/public/js/core",
     "mojo/public/js/validator",
-{%-   for import in imports %}
+{%- for import in imports %}
     "{{import.module.path}}",
-{%-   endfor %}
+{%- endfor %}
 ], function(
 {%- if module.path != "mojo/public/interfaces/bindings/interface_control_messages.mojom" -%}
 bindings, {% endif -%}
 codec, core, validator
-{%-   for import in imports -%}
+{%- for import in imports -%}
     , {{import.unique_name}}
-{%-   endfor -%}
+{%- endfor -%}
 ) {
 
 {%- include "module_definition.tmpl" %}
 
   return exports;
 });
-
-{%- endif %}
\ No newline at end of file
diff --git a/mojo/public/tools/bindings/generators/js_templates/module_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/module_definition.tmpl
index 5abcf34f..ddfef72 100644
--- a/mojo/public/tools/bindings/generators/js_templates/module_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/module_definition.tmpl
@@ -1,5 +1,5 @@
 {#--- Constants #}
-{%- for constant in module.constants %}
+{%-  for constant in module.constants %}
   var {{constant.name}} = {{constant.value|expression_to_text}};
 {%- endfor %}
 
@@ -25,13 +25,8 @@
 {%-   include "interface_definition.tmpl" %}
 {%- endfor %}
 
-{%- if use_new_js_bindings %}
-  var exports = mojoBindings.internal.exposeNamespace("{{module.namespace}}");
-{%- else %}
   var exports = {};
-{%- endif %}
-
-{%- for constant in module.constants %}
+{%-  for constant in module.constants %}
   exports.{{constant.name}} = {{constant.name}};
 {%- endfor %}
 {%- for enum in enums %}
@@ -46,4 +41,10 @@
 {%- for interface in interfaces %}
   exports.{{interface.name}} = {{interface.name}};
   exports.{{interface.name}}Ptr = {{interface.name}}Ptr;
+{#--- Interface Client #}
+{%-   if interface.client in interfaces|map(attribute='name') %}
+  exports.{{interface.name}}.client = {{interface.client}};
+{%-   elif interface.client in imported_interfaces %}
+  exports.{{interface.name}}.client = {{imported_interfaces[interface.client]}};
+{%-   endif %}
 {%- endfor %}
diff --git a/mojo/public/tools/bindings/generators/mojom_js_generator.py b/mojo/public/tools/bindings/generators/mojom_js_generator.py
index 6184f6d..0eedb31 100644
--- a/mojo/public/tools/bindings/generators/mojom_js_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_js_generator.py
@@ -368,7 +368,6 @@
       "module": self.module,
       "structs": self.GetStructs() + self.GetStructsFromMethods(),
       "unions": self.GetUnions(),
-      "use_new_js_bindings": self.use_new_js_bindings,
       "interfaces": self.GetInterfaces(),
       "imported_interfaces": self.GetImportedInterfaces(),
     }
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni
index 4a244fb5..2466636 100644
--- a/mojo/public/tools/bindings/mojom.gni
+++ b/mojo/public/tools/bindings/mojom.gni
@@ -134,13 +134,6 @@
 #   cpp_only (optional)
 #       If set to true, only the C++ bindings targets will be generated.
 #
-#   use_new_js_bindings (optional)
-#       If set to true, the generated JS code will use the new module loading
-#       approach and the core API exposed by Web IDL.
-#
-#       TODO(yzshen): Switch all existing users to use_new_js_bindings=true and
-#       remove the old mode.
-#
 # The following parameters are used to support the component build. They are
 # needed so that bindings which are linked with a component can use the same
 # export settings for classes. The first three are for the chromium variant, and
@@ -441,11 +434,6 @@
         if (defined(invoker.use_once_callback) && invoker.use_once_callback) {
           args += [ "--use_once_callback" ]
         }
-
-        if (defined(invoker.use_new_js_bindings) &&
-            invoker.use_new_js_bindings) {
-          args += [ "--use_new_js_bindings" ]
-        }
       }
     }
 
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.py b/mojo/public/tools/bindings/mojom_bindings_generator.py
index a9650d7..3a0b6fc8 100755
--- a/mojo/public/tools/bindings/mojom_bindings_generator.py
+++ b/mojo/public/tools/bindings/mojom_bindings_generator.py
@@ -167,7 +167,6 @@
             variant=args.variant, bytecode_path=args.bytecode_path,
             for_blink=args.for_blink,
             use_once_callback=args.use_once_callback,
-            use_new_js_bindings=args.use_new_js_bindings,
             export_attribute=args.export_attribute,
             export_header=args.export_header,
             generate_non_variant_code=args.generate_non_variant_code)
@@ -299,10 +298,6 @@
       "--use_once_callback", action="store_true",
       help="Use base::OnceCallback instead of base::RepeatingCallback.")
   generate_parser.add_argument(
-      "--use_new_js_bindings", action="store_true",
-      help="Use the new module loading approach and the core API exposed by "
-      "Web IDL. This option only affects the JavaScript bindings.")
-  generate_parser.add_argument(
       "--export_attribute", type=str, default="",
       help="Optional attribute to specify on class declaration to export it "
       "for the component build.")
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/generator.py b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
index 0e64af7..e4ab3735 100644
--- a/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
@@ -38,8 +38,8 @@
   # files to stdout.
   def __init__(self, module, output_dir=None, typemap=None, variant=None,
                bytecode_path=None, for_blink=False, use_once_callback=False,
-               use_new_js_bindings=False, export_attribute=None,
-               export_header=None, generate_non_variant_code=False):
+               export_attribute=None, export_header=None,
+               generate_non_variant_code=False):
     self.module = module
     self.output_dir = output_dir
     self.typemap = typemap or {}
@@ -47,7 +47,6 @@
     self.bytecode_path = bytecode_path
     self.for_blink = for_blink
     self.use_once_callback = use_once_callback
-    self.use_new_js_bindings = use_new_js_bindings
     self.export_attribute = export_attribute
     self.export_header = export_header
     self.generate_non_variant_code = generate_non_variant_code
diff --git a/services/device/BUILD.gn b/services/device/BUILD.gn
index de1ecce..fbcee0c 100644
--- a/services/device/BUILD.gn
+++ b/services/device/BUILD.gn
@@ -11,6 +11,9 @@
 }
 
 source_set("lib") {
+  # This should be visible only to embedders of the Device Service, and the
+  # dependence should only be for the purpose of embedding the Device Service.
+  visibility = [ "//content/browser" ]
   sources = [
     "device_service.cc",
     "device_service.h",
@@ -87,11 +90,13 @@
   }
 
   android_library("java") {
-    java_files = [
-      "android/java/src/org/chromium/services/device/InterfaceRegistrar.java",
-      "screen_orientation/android/java/src/org/chromium/device/screen_orientation/ScreenOrientationListener.java",
-      "time_zone_monitor/android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java",
-    ]
+    # This should be visible only to embedders of the Device Service, and the
+    # dependence should only be for the purpose of embedding the Device Service.
+    # //content/public/android:* here actually wants to identify the
+    # //content/public/android:content_java target and all of its generated
+    # targets which also need to see this target as well.
+    visibility = [ "//content/public/android:*" ]
+    java_files = [ "android/java/src/org/chromium/services/device/InterfaceRegistrar.java" ]
     deps = [
       "//base:base_java",
       "//device/battery:mojo_bindings_java",
@@ -101,9 +106,10 @@
       "//mojo/android:system_java",
       "//mojo/public/java:bindings_java",
       "//mojo/public/java:system_java",
+      "//services/device/screen_orientation:java",
+      "//services/device/time_zone_monitor:java",
       "//services/service_manager/public/interfaces:interfaces_java",
       "//services/service_manager/public/java:service_manager_java",
-      "//ui/android:ui_java",
     ]
   }
 }
diff --git a/services/device/screen_orientation/BUILD.gn b/services/device/screen_orientation/BUILD.gn
index be91f8d..6aa31af 100644
--- a/services/device/screen_orientation/BUILD.gn
+++ b/services/device/screen_orientation/BUILD.gn
@@ -38,4 +38,16 @@
     ]
     jni_package = "screen_orientation"
   }
+
+  android_library("java") {
+    # Conceptually, this should be visible only to //services/device:java.
+    # However, various generated targets also need to see this target as a
+    # result of //services/device:java depending on it.
+    visibility = [ "//services/device:*" ]
+    java_files = [ "android/java/src/org/chromium/device/screen_orientation/ScreenOrientationListener.java" ]
+    deps = [
+      "//base:base_java",
+      "//ui/android:ui_java",
+    ]
+  }
 }
diff --git a/services/device/time_zone_monitor/BUILD.gn b/services/device/time_zone_monitor/BUILD.gn
index ecef1fc3..14cba6d 100644
--- a/services/device/time_zone_monitor/BUILD.gn
+++ b/services/device/time_zone_monitor/BUILD.gn
@@ -61,4 +61,15 @@
     ]
     jni_package = "time_zone_monitor"
   }
+
+  android_library("java") {
+    # Conceptually, this should be visible only to //services/device:java.
+    # However, various generated targets also need to see this target as a
+    # result of //services/device:java depending on it.
+    visibility = [ "//services/device:*" ]
+    java_files = [ "android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java" ]
+    deps = [
+      "//base:base_java",
+    ]
+  }
 }
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index ca0334c9..8c356fb 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1805,6 +1805,7 @@
 # Working on getting the CSP tests going:
 crbug.com/694525 external/wpt/content-security-policy [ Skip ]
 crbug.com/694525 external/wpt/content-security-policy/connect-src [ Pass ]
+crbug.com/694525 external/wpt/content-security-policy/img-src [ Pass ]
 crbug.com/694525 external/wpt/content-security-policy/inside-worker [ Pass ]
 crbug.com/694525 external/wpt/content-security-policy/media-src [ Pass ]
 crbug.com/694525 external/wpt/content-security-policy/securitypolicyviolation [ Pass ]
@@ -2280,6 +2281,10 @@
 crbug.com/658997 external/wpt/service-workers/service-worker/invalid-header.https.html [ Skip ]
 crbug.com/658997 external/wpt/service-workers/service-worker/referer.https.html [ Skip ]
 
+crbug.com/435547 external/wpt/service-workers/cache-storage/serviceworker/credentials.https.html [ Skip ]
+crbug.com/435547 http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html [ Skip ]
+crbug.com/435547 virtual/mojo-loading/http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html [ Skip ]
+
 crbug.com/697971 [ Mac10.12 ] fast/text/flexbox-selection-nested.html [ Skip ]
 crbug.com/697971 [ Mac10.12 ] fast/text/flexbox-selection.html [ Skip ]
 crbug.com/697971 [ Mac10.12 ] http/tests/inspector/appcache/appcache-manifest-with-non-existing-file.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-4_1.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-4_1.html
deleted file mode 100644
index edf04fb..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-4_1.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-    <title>img element src attribute must match src list.</title>
-    <script src='/resources/testharness.js'></script>
-    <script src='/resources/testharnessreport.js'></script>
-</head>
-<body>
-    <h1>img element src attribute must match src list.</h1>
-    <p>
-    <div id='log'></div>
-
-    <script type="text/javascript">
-      var t1 = async_test("img-src for relative path should load.");
-      var t2 = async_test("img-src from unapproved domains should not load");
-      var t3 = async_test("img-src from approved domains should load");
-    </script>
-
-    <img src='/content-security-policy/support/pass.png'
-    onerror='t1.step(function() { assert_unreached("The img should have loaded."); t1.done() });'
-    onload='t1.done();'>
-
-    <img src='http://www1.web-platform.test/content-security-policy/support/fail.png'
-    onerror='t2.done();'
-    onload='t2.step(function() { assert_unreached("Image from unapproved domain was loaded."); t2.done()} );'>
-
-    <div id='t3'></div>
-
-    <script>
-      var t3img = document.createElement('img');
-      t3img.onerror = function() {t3.step(function() { assert_unreached(); t3.done();})}
-      t3img.onload = function() {t3.done();}
-      t3img.src = location.protocol + '//www.' + location.hostname + ':' + location.port +
-           '/content-security-policy/support/pass.png';
-      var t3div = document.getElementById('t3');
-      t3div.appendChild(t3img);
-
-      var report = document.createElement('script');
-      report.src = '../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27self%27%20www.' + location.hostname + (location.port ? ':' + location.port : '');
-      t3div.appendChild(report);
-
-    </script>
-
-
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-4_1.html.sub.headers b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-4_1.html.sub.headers
deleted file mode 100644
index 543e48c1..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-4_1.html.sub.headers
+++ /dev/null
@@ -1,6 +0,0 @@
-Expires: Mon, 26 Jul 1997 05:00:00 GMT
-Cache-Control: no-store, no-cache, must-revalidate
-Cache-Control: post-check=0, pre-check=0, false
-Pragma: no-cache
-Set-Cookie: img-src-4_1={{$id:uuid()}}; Path=/content-security-policy/img-src/
-Content-Security-Policy: img-src 'self' www.{{host}}:{{ports[http][0]}};  report-uri  ../support/report.py?op=put&reportID={{$id}}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-4_1.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-4_1.sub.html
new file mode 100644
index 0000000..9e4e345
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-4_1.sub.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<meta http-equiv="Content-Security-Policy" content="img-src 'self' {{domains[www]}}:{{ports[http][0]}}">
+<html>
+<head>
+    <title>img element src attribute must match src list.</title>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+    <div id='log'/>
+
+    <script>
+      async_test(function(t) {
+        i = new Image();
+        i.onload = t.step_func_done();
+        i.onerror = t.unreached_func("The img should have loaded");
+        i.src = '/content-security-policy/support/pass.png';
+      }, "img-src for relative path should load");
+
+      async_test(function(t) {
+        i = new Image();
+        i.onload = t.unreached_func("Image from unapproved domain was loaded.");
+        i.onerror = t.step_func_done();
+        i.src = 'http://{{domains[www1]}}/content-security-policy/support/fail.png';
+      }, "img-src from unapproved domains should not load");
+
+      async_test(function(t) {
+        i = new Image();
+        i.onload = t.step_func_done();
+        i.onerror = t.unreached_func("The img should have loaded");
+        i.src = location.protocol + '//{{domains[www]}}:{{ports[http][0]}}/content-security-policy/support/pass.png';
+      }, "img-src from approved domains should load");
+    </script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-full-host-wildcard-blocked.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-full-host-wildcard-blocked.sub.html
new file mode 100644
index 0000000..23c33d56
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-full-host-wildcard-blocked.sub.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta http-equiv="Content-Security-Policy" content="img-src *.{{host}}:{{ports[http][0]}}">
+<html>
+<head>
+    <title>img-src with full host and wildcard blocks correctly.</title>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+    <div id='log'/>
+
+    <script>
+      var t1 = async_test("img src does not match full host and wildcard csp directive");
+    </script>
+    <img src='http://{{host}}:{{ports[http][0]}}/content-security-policy/support/fail.png'
+         onload='t1.step(function() { assert_unreached("Image should have loaded"); t1.done(); });'
+         onerror='t1.done();'>
+
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-host-partial-wildcard-allowed.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-host-partial-wildcard-allowed.sub.html
new file mode 100644
index 0000000..d2d36d13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-host-partial-wildcard-allowed.sub.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta http-equiv="Content-Security-Policy" content="img-src *.{{host}}:{{ports[http][0]}}">
+<html>
+<head>
+    <title>img-src works correctly with partial host wildcard.</title>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+    <div id='log'/>
+
+    <script>
+      var t1 = async_test("img src matches correctly partial wildcard host csp directive");
+    </script>
+    <img src='http://{{domains[www]}}:{{ports[http][0]}}/content-security-policy/support/pass.png'
+         onload='t1.done();'
+         onerror='t1.step(function() { assert_unreached("Image should have loaded"); t1.done(); });'>
+
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-none-blocks.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-none-blocks.html
new file mode 100644
index 0000000..9bc0326e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-none-blocks.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta http-equiv="Content-Security-Policy" content="img-src 'none';">
+<html>
+<head>
+    <title>img element src attribute must match src list.</title>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+    <div id='log'/>
+
+    <script>
+      var t1 = async_test("img-src with 'none' source should not match");
+    </script>
+    <img src='/content-security-policy/support/fail.png'
+         onload='t1.step(function() { assert_unreached("Image should not have loaded"); t1.done(); });'
+         onerror='t1.done();'>
+
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-port-wildcard-allowed.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-port-wildcard-allowed.sub.html
new file mode 100644
index 0000000..215c1008
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-port-wildcard-allowed.sub.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<meta http-equiv="Content-Security-Policy" content="img-src http://www.{{host}}:*">
+<html>
+<head>
+    <title>img-src works correctly with port wildcard source</title>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+    <div id='log'/>
+
+    <script>
+      var t1 = async_test("img-src with wildcard port should match any port");
+    </script>
+    <img src='http://{{domains[www]}}:{{ports[http][0]}}/content-security-policy/support/pass.png'
+         onload='t1.done();'
+         onerror='t1.step(function() { assert_unreached("Image should have loaded."); t1.done()} );'>
+
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-wildcard-allowed.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-wildcard-allowed.html
new file mode 100644
index 0000000..72326ee
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/img-src/img-src-wildcard-allowed.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta http-equiv="Content-Security-Policy" content="img-src *;">
+<html>
+<head>
+    <title>img element src attribute must match src list.</title>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+</head>
+<body>
+    <div id='log'/>
+
+    <script>
+      var t1 = async_test("img-src with wildcard should match all");
+    </script>
+    <img src='/content-security-policy/support/pass.png'
+         onload='t1.done();'
+         onerror='t1.step(function() { assert_unreached("Image should have loaded"); t1.done(); });'>
+
+    <script>
+      async_test(function(t) {
+
+        var pngBase64 = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAnklEQVR42u3QMQEAAAgDoGlyo1vBzwciUJlw1ApkyZIlS5YsBbJkyZIlS5YCWbJkyZIlS4EsWbJkyZKlQJYsWbJkyVIgS5YsWbJkKZAlS5YsWbIUyJIlS5YsWQpkyZIlS5YsBbJkyZIlS5YCWbJkyZIlS4EsWbJkyZKlQJYsWbJkyVIgS5YsWbJkKZAlS5YsWbIUyJIlS5YsWQpkyfq2MosBSIeKONMAAAAASUVORK5CYII=";
+
+        blobContents = [atob(pngBase64)];
+        blob = new Blob(blobContents, {type: "image/png"});
+        img = document.createElement("img");
+        img.onerror = function (e) {
+          t.done();
+        };
+        img.onload = function () {
+          assert_unreached("Should not load blob img");
+          t.done();
+        };
+        blobURL = window.URL.createObjectURL(blob);
+        img.src = blobURL;
+
+      },"img-src with wildcard should not match blob");
+    </script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
new file mode 100644
index 0000000..dd9dc31
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
@@ -0,0 +1,57 @@
+This is a testharness.js-based test.
+PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors without credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, cors mode Request redirected to cors without credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors without credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors without credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin without credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected 
+PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected 
+PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors with credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, cors mode Request redirected to cors with credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors with credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors with credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin with credentials should fail opaqueredirect interception and response should not be redirected 
+PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected 
+PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected 
+PASS Non-navigation, follow redirect, cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected 
+PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, follow redirect, cors mode Request redirected to cors without credentials should succeed interception and response should be redirected 
+PASS Non-navigation, follow redirect, same-origin mode Request redirected to same-origin without credentials should succeed interception and response should be redirected 
+PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, follow redirect, no-cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected 
+PASS Non-navigation, follow redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected 
+PASS Non-navigation, follow redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected 
+FAIL Non-navigation, follow redirect, cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
+PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected 
+PASS Non-navigation, follow redirect, cors mode Request redirected to cors with credentials should fail interception and response should be redirected 
+FAIL Non-navigation, follow redirect, same-origin mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
+PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected 
+PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected 
+FAIL Non-navigation, follow redirect, no-cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
+FAIL Non-navigation, follow redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
+FAIL Non-navigation, follow redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected assert_unreached: unexpected rejection: TypeError: Failed to fetch Reached unreachable code
+PASS Non-navigation, error redirect, cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, cors mode Request redirected to cors without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, no-cors mode Request redirected to cors without credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, cors mode Request redirected to cors with credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin with credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected 
+PASS Non-navigation, error redirect, no-cors mode Request redirected to cors with credentials should fail interception and response should not be redirected 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/credentials-iframe.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/credentials-iframe.html
index 00702df9..946dedc5 100644
--- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/credentials-iframe.html
+++ b/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/credentials-iframe.html
@@ -22,7 +22,7 @@
 
 window.onmessage = function(e) {
   Promise.all(e.data.map(function(item) {
-    return xhr(item.name, item.username, item.password);
+    return xhr(item.name, item.username, item.password).catch(_ => {});
   }))
     .then(function() {
       navigator.serviceWorker.controller.postMessage('keys');
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/credentials.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/credentials.html
index 1bceb40..0bd1556 100644
--- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/credentials.html
+++ b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/credentials.html
@@ -34,12 +34,12 @@
       });
     })
     .then(function(data) {
-      assert_equals(data.length, 3, 'three entries should be present');
-      assert_equals(data.filter(function(url) { return /@/.test(url); }).length, 2,
+      assert_equals(data.length, 1, 'three entries should be present');
+      assert_equals(data.filter(function(url) { return /@/.test(url); }).length, 0,
         'two entries should contain credentials');
-      assert_true(data.some(function(url) { return /aa:bb@/.test(url); }),
+      assert_false(data.some(function(url) { return /aa:bb@/.test(url); }),
         'entry with credentials aa:bb should be present');
-      assert_true(data.some(function(url) { return /cc:dd@/.test(url); }),
+      assert_false(data.some(function(url) { return /cc:dd@/.test(url); }),
         'entry with credentials cc:dd should be present');
     });
 });
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect-password.js b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect-password.js
index 6fbe5cc..1bc0677 100644
--- a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect-password.js
+++ b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/thorough/redirect-password.js
@@ -4,8 +4,9 @@
 }
 
 var TEST_TARGETS = [
-  // Redirects to URLs with username/password.
-  // Spec: https://fetch.spec.whatwg.org/#concept-http-fetch
+  // Redirects to URLs with username/password; these requests are blocked.
+  //
+  // Spec: https://github.com/whatwg/fetch/pull/465
   // Step 5, redirect status, Step 10.1 and 10.2:
   // "If |request|'s mode is "cors", |request|'s origin is not same origin with
   //  |locationURL|'s origin, and |locationURL| includes credentials, return a
@@ -16,34 +17,22 @@
   // Origin A -[fetch]-> Origin A -[redirect]-> Origin A
   [REDIRECT_URL + encodeURIComponent(BASE_URL_WITH_USERNAME) +
    '&mode=same-origin&method=GET',
-   [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeBasic,
-    responseRedirected, checkURLList.bind(self, [BASE_URL_WITH_USERNAME])],
-   [methodIsGET]],
+   [fetchRejected]],
   [REDIRECT_URL + encodeURIComponent(BASE_URL_WITH_PASSWORD) +
    '&mode=same-origin&method=GET',
-   [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeBasic,
-    responseRedirected, checkURLList.bind(self, [BASE_URL_WITH_PASSWORD])],
-   [methodIsGET]],
+   [fetchRejected]],
   [REDIRECT_URL + encodeURIComponent(BASE_URL_WITH_USERNAME) +
    '&mode=cors&method=GET',
-   [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeBasic,
-    responseRedirected, checkURLList.bind(self, [BASE_URL_WITH_USERNAME])],
-   [methodIsGET]],
+   [fetchRejected]],
   [REDIRECT_URL + encodeURIComponent(BASE_URL_WITH_PASSWORD) +
    '&mode=cors&method=GET',
-   [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeBasic,
-    responseRedirected, checkURLList.bind(self, [BASE_URL_WITH_PASSWORD])],
-   [methodIsGET]],
+   [fetchRejected]],
   [REDIRECT_URL + encodeURIComponent(BASE_URL_WITH_USERNAME) +
    '&mode=no-cors&method=GET',
-   [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeBasic,
-    responseRedirected, checkURLList.bind(self, [BASE_URL_WITH_USERNAME])],
-   [methodIsGET]],
+   [fetchRejected]],
   [REDIRECT_URL + encodeURIComponent(BASE_URL_WITH_PASSWORD) +
    '&mode=no-cors&method=GET',
-   [fetchResolved, hasContentLength, hasServerHeader, hasBody, typeBasic,
-    responseRedirected, checkURLList.bind(self, [BASE_URL_WITH_PASSWORD])],
-   [methodIsGET]],
+   [fetchRejected]],
 
   // Origin A -[fetch]-> Origin A -[redirect]-> Origin B
   [REDIRECT_URL +
@@ -57,17 +46,11 @@
   [REDIRECT_URL +
    encodeURIComponent(OTHER_BASE_URL_WITH_USERNAME + '&ACAOrigin=*') +
    '&mode=no-cors&method=GET',
-   [fetchResolved, noContentLength, noServerHeader, noBody, typeOpaque,
-    responseNotRedirected,
-    checkURLList.bind(self, [OTHER_BASE_URL_WITH_USERNAME + '&ACAOrigin=*'])],
-   onlyOnServiceWorkerProxiedTest([methodIsGET])],
+   [fetchRejected]],
   [REDIRECT_URL +
    encodeURIComponent(OTHER_BASE_URL_WITH_PASSWORD + '&ACAOrigin=*') +
    '&mode=no-cors&method=GET',
-   [fetchResolved, noContentLength, noServerHeader, noBody, typeOpaque,
-    responseNotRedirected,
-    checkURLList.bind(self, [OTHER_BASE_URL_WITH_PASSWORD + '&ACAOrigin=*'])],
-   onlyOnServiceWorkerProxiedTest([methodIsGET])],
+   [fetchRejected]],
 
   // Origin A -[fetch]-> Origin B -[redirect]-> Origin A
   [OTHER_REDIRECT_URL +
@@ -81,17 +64,11 @@
   [OTHER_REDIRECT_URL +
    encodeURIComponent(BASE_URL_WITH_USERNAME + 'ACAOrigin=*') +
    '&mode=no-cors&method=GET&ACAOrigin=*',
-   [fetchResolved, noContentLength, noServerHeader, noBody, typeOpaque,
-    responseNotRedirected,
-    checkURLList.bind(self, [BASE_URL_WITH_USERNAME + 'ACAOrigin=*'])],
-   onlyOnServiceWorkerProxiedTest([methodIsGET])],
+   [fetchRejected]],
   [OTHER_REDIRECT_URL +
    encodeURIComponent(BASE_URL_WITH_PASSWORD + 'ACAOrigin=*') +
    '&mode=no-cors&method=GET&ACAOrigin=*',
-   [fetchResolved, noContentLength, noServerHeader, noBody, typeOpaque,
-    responseNotRedirected,
-    checkURLList.bind(self, [BASE_URL_WITH_PASSWORD + 'ACAOrigin=*'])],
-   onlyOnServiceWorkerProxiedTest([methodIsGET])],
+   [fetchRejected]],
 
   // Origin A -[fetch]-> Origin B -[redirect]-> Origin B
   [OTHER_REDIRECT_URL +
@@ -105,17 +82,11 @@
   [OTHER_REDIRECT_URL +
    encodeURIComponent(OTHER_BASE_URL_WITH_USERNAME + 'ACAOrigin=*') +
    '&mode=no-cors&method=GET&ACAOrigin=*',
-   [fetchResolved, noContentLength, noServerHeader, noBody, typeOpaque,
-    responseNotRedirected,
-    checkURLList.bind(self, [OTHER_BASE_URL_WITH_USERNAME + 'ACAOrigin=*'])],
-   onlyOnServiceWorkerProxiedTest([methodIsGET])],
+   [fetchRejected]],
   [OTHER_REDIRECT_URL +
    encodeURIComponent(OTHER_BASE_URL_WITH_PASSWORD + 'ACAOrigin=*') +
    '&mode=no-cors&method=GET&ACAOrigin=*',
-   [fetchResolved, noContentLength, noServerHeader, noBody, typeOpaque,
-    responseNotRedirected,
-    checkURLList.bind(self, [OTHER_BASE_URL_WITH_PASSWORD + 'ACAOrigin=*'])],
-   onlyOnServiceWorkerProxiedTest([methodIsGET])],
+   [fetchRejected]],
 ];
 
 if (self.importScripts) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-xhr-replay-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-xhr-replay-expected.txt
index 74a32a4..7b37f08 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-xhr-replay-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-xhr-replay-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: line 37: Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are deprecated, and will be blocked in M59, around June 2017. See https://www.chromestatus.com/feature/5669008342777856 for more details.
 CONSOLE MESSAGE: line 6: XHR loaded: 1
 CONSOLE WARNING: line 33: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
 CONSOLE MESSAGE: line 6: XHR loaded: 2
@@ -12,50 +11,50 @@
 
 Running: testGetStaticAsync
 Dumping request: 
-    url: http://user:password@127.0.0.1:8000/inspector/network/resources/empty.html
+    url: http://127.0.0.1:8000/inspector/network/resources/empty.html
     requestMethod: GET
     test request header value: headerValueA
 
 Running: testGetStaticSync
 Dumping request: 
-    url: http://user:password@127.0.0.1:8000/inspector/network/resources/empty.html
+    url: http://127.0.0.1:8000/inspector/network/resources/empty.html
     requestMethod: GET
     test request header value: headerValueB
 
 Running: testGetCachedAsync
 Dumping request: 
-    url: http://user:password@127.0.0.1:8000/inspector/network/resources/random-cached.php
+    url: http://127.0.0.1:8000/inspector/network/resources/random-cached.php
     requestMethod: GET
     test request header value: headerValueC
 
 Running: testGetCachedSync
 Dumping request: 
-    url: http://user:password@127.0.0.1:8000/inspector/network/resources/random-cached.php
+    url: http://127.0.0.1:8000/inspector/network/resources/random-cached.php
     requestMethod: GET
     test request header value: headerValueD
 
 Running: testGetRandomAsync
 Dumping request: 
-    url: http://user:password@127.0.0.1:8000/inspector/network/resources/random.php
+    url: http://127.0.0.1:8000/inspector/network/resources/random.php
     requestMethod: GET
     test request header value: headerValueE
 
 Running: testGetRandomSync
 Dumping request: 
-    url: http://user:password@127.0.0.1:8000/inspector/network/resources/random.php
+    url: http://127.0.0.1:8000/inspector/network/resources/random.php
     requestMethod: GET
     test request header value: headerValueF
 
 Running: testPostAsync
 Dumping request: 
-    url: http://user:password@127.0.0.1:8000/inspector/network/resources/random.php
+    url: http://127.0.0.1:8000/inspector/network/resources/random.php
     requestFormData: payload
     requestMethod: POST
     test request header value: headerValueG
 
 Running: testPostSync
 Dumping request: 
-    url: http://user:password@127.0.0.1:8000/inspector/network/resources/random.php
+    url: http://127.0.0.1:8000/inspector/network/resources/random.php
     requestFormData: payload
     requestMethod: POST
     test request header value: headerValueH
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-xhr-replay.html b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-xhr-replay.html
index c8f083e..f5ad050 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-xhr-replay.html
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-xhr-replay.html
@@ -54,42 +54,42 @@
     InspectorTest.runTestSuite([
         function testGetStaticAsync(next)
         {
-            testXHRReplay("GET", "resources/empty.html", true, "user", "password", [["headerName", "headerValueA"]], false, undefined, undefined, next);
+            testXHRReplay("GET", "resources/empty.html", true, null, null, [["headerName", "headerValueA"]], false, undefined, undefined, next);
         },
 
         function testGetStaticSync(next)
         {
-            testXHRReplay("GET", "resources/empty.html", false, "user", "password", [["headerName", "headerValueB"]], false, undefined, undefined, next);
+            testXHRReplay("GET", "resources/empty.html", false, null, null, [["headerName", "headerValueB"]], false, undefined, undefined, next);
         },
 
         function testGetCachedAsync(next)
         {
-            testXHRReplay("GET", "resources/random-cached.php", true, "user", "password", [["headerName", "headerValueC"]], false, undefined, undefined, next);
+            testXHRReplay("GET", "resources/random-cached.php", true, null, null, [["headerName", "headerValueC"]], false, undefined, undefined, next);
         },
 
         function testGetCachedSync(next)
         {
-            testXHRReplay("GET", "resources/random-cached.php", false, "user", "password", [["headerName", "headerValueD"]], false, undefined, undefined, next);
+            testXHRReplay("GET", "resources/random-cached.php", false, null, null, [["headerName", "headerValueD"]], false, undefined, undefined, next);
         },
 
         function testGetRandomAsync(next)
         {
-            testXHRReplay("GET", "resources/random.php", true, "user", "password", [["headerName", "headerValueE"]], false, undefined, undefined, next);
+            testXHRReplay("GET", "resources/random.php", true, null, null, [["headerName", "headerValueE"]], false, undefined, undefined, next);
         },
 
         function testGetRandomSync(next)
         {
-            testXHRReplay("GET", "resources/random.php", false, "user", "password", [["headerName", "headerValueF"]], false, undefined, undefined, next);
+            testXHRReplay("GET", "resources/random.php", false, null, null, [["headerName", "headerValueF"]], false, undefined, undefined, next);
         },
 
         function testPostAsync(next)
         {
-            testXHRReplay("POST", "resources/random.php", true, "user", "password", [["headerName", "headerValueG"]], false, "payload", undefined, next);
+            testXHRReplay("POST", "resources/random.php", true, null, null, [["headerName", "headerValueG"]], false, "payload", undefined, next);
         },
 
         function testPostSync(next)
         {
-            testXHRReplay("POST", "resources/random.php", false, "user", "password", [["headerName", "headerValueH"]], false, "payload", undefined, next);
+            testXHRReplay("POST", "resources/random.php", false, null, null, [["headerName", "headerValueH"]], false, "payload", undefined, next);
         }
     ]);
 }
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-allowed-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-allowed-expected.txt
deleted file mode 100644
index 9c7032118..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-allowed-expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-ALERT: PASS
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-allowed.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-allowed.html
deleted file mode 100644
index 406c0542..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-allowed.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Security-Policy" content="img-src *; script-src 'unsafe-inline'">
-<script>
-if (window.testRunner)
-    testRunner.dumpAsText();
-</script>
-</head>
-<body>
-<img src="../resources/abe.png" onload="alert(this.width == 76 ? 'PASS' : 'FAIL')">
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-blocked-alt-content.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-blocked-alt-content.html
deleted file mode 100644
index de590c10..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-blocked-alt-content.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Security-Policy" content="img-src 'self'; script-src 'unsafe-inline'">
-</head>
-<body>
-This test shows what alt content looks like when an image errors out on a page with a CSP that blocks data: URIs for images.
-<img src="../resources/ab.png" width="50px;" height="50px;" alt="alt text">
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-blocked-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-blocked-expected.txt
deleted file mode 100644
index b80b35d..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-blocked-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CONSOLE ERROR: Refused to load the image 'http://127.0.0.1:8000/security/resources/abe.png' because it violates the following Content Security Policy directive: "img-src 'none'".
-
-ALERT: PASS
-This test passes if it doesn't alert FAIL and does alert PASS. 
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-blocked.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-blocked.html
deleted file mode 100644
index 3b9d061..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-blocked.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Security-Policy" content="img-src 'none'; script-src 'unsafe-inline'">
-<script>
-if (window.testRunner)
-    testRunner.dumpAsText();
-</script>
-</head>
-<body>
-This test passes if it doesn't alert FAIL and does alert PASS.
-<img src="../resources/abe.png" onload="alert('FAIL')" onerror="alert('PASS')">
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-full-host-wildcard-fails-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-full-host-wildcard-fails-expected.txt
deleted file mode 100644
index b15522a..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-full-host-wildcard-fails-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CONSOLE ERROR: Refused to load the image 'http://127.0.0.1:8000/security/resources/abe.png' because it violates the following Content Security Policy directive: "img-src *.127.0.0.1:8000".
-
-ALERT: PASS
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-full-host-wildcard-fails.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-full-host-wildcard-fails.html
deleted file mode 100644
index 250aa842..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-full-host-wildcard-fails.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Security-Policy" content="img-src *.127.0.0.1:8000; script-src 'unsafe-inline'">
-<script>
-if (window.testRunner)
-    testRunner.dumpAsText();
-</script>
-</head>
-<body>
-<img src="../resources/abe.png" onerror="alert('PASS')">
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-host-wildcard-allowed-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-host-wildcard-allowed-expected.txt
deleted file mode 100644
index 9c7032118..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-host-wildcard-allowed-expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-ALERT: PASS
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-host-wildcard-allowed.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-host-wildcard-allowed.html
deleted file mode 100644
index f060e0f5..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/image-host-wildcard-allowed.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Security-Policy" content="img-src *.0.1:8000; script-src 'unsafe-inline'">
-<script>
-if (window.testRunner)
-    testRunner.dumpAsText();
-</script>
-</head>
-<body>
-<img src="../resources/abe.png" onload="alert(this.width == 76 ? 'PASS' : 'FAIL')">
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/location-href-clears-username-password-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/location-href-clears-username-password-expected.txt
index 9752bd9..1521acf8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/location-href-clears-username-password-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/location-href-clears-username-password-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: line 17: Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are deprecated, and will be blocked in M59, around June 2017. See https://www.chromestatus.com/feature/5669008342777856 for more details.
 ALERT: PASS
 This test passes if it alerts the string "PASS".
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/location-href-clears-username-password.html b/third_party/WebKit/LayoutTests/http/tests/security/location-href-clears-username-password.html
index 74f7decd..87fc32b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/location-href-clears-username-password.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/location-href-clears-username-password.html
@@ -8,23 +8,20 @@
     {
         testRunner.dumpAsText();
         testRunner.waitUntilDone();
+        testRunner.setCanOpenWindows(true);
     }
 
-    var div = document.getElementById('div1');
-    var frame = document.createElement('iframe');
-    frame.setAttribute('src', 'http://_username:_password@' 
-        + location.host + '/security/resources/blank.html');
-    document.body.appendChild(frame);
-
-    frame.onload = function() {
-        var href = frame.contentWindow.location.href;
+    window.addEventListener("message", e => {
+        var href = e.data.location;
         if (href.indexOf('_username') === -1 &&
             href.indexOf('_password') === -1) {
             alert('PASS');
         }
         if (window.testRunner)
             testRunner.notifyDone();
-    }
+    });
+
+    var w = window.open('http://_username:_password@127.0.0.1:8000/security/resources/post-location-to-opener.html');
 }
 </script>
 </head>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/resources/post-location-to-opener.html b/third_party/WebKit/LayoutTests/http/tests/security/resources/post-location-to-opener.html
new file mode 100644
index 0000000..10a38ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/security/resources/post-location-to-opener.html
@@ -0,0 +1,3 @@
+<script>
+    opener.postMessage({ 'location': location.href }, '*');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-access-control-login.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-access-control-login.html
index 4152c669..1dad1c8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-access-control-login.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-access-control-login.html
@@ -1,16 +1,16 @@
 <script>
 // Set authentication info
+var port;
+var w;
 window.addEventListener("message", function(evt) {
-    var port = evt.ports[0];
+  if (evt.ports[0]) {
+    port = evt.ports[0];
     document.cookie = 'cookie=' + evt.data.cookie;
-    var xhr = new XMLHttpRequest();
-    xhr.addEventListener('load', function() {
-        port.postMessage({msg: 'LOGIN FINISHED'});
-      }, false);
-    xhr.open('GET',
-             './fetch-access-control.php?Auth',
-             true,
-             evt.data.username, evt.data.password);
-    xhr.send();
-  }, false);
-</script>
\ No newline at end of file
+    w = window.open(window.location.protocol + "//" + evt.data.username + ":" + evt.data.password + "@" + window.location.hostname + ":" + window.location.port + "/serviceworker/resources/fetch-access-control.php?Auth&WINDOW", evt.data.username);
+  } else {
+    w.close();
+    w = null;
+    port.postMessage({msg: 'LOGIN FINISHED'});
+  }
+}, false);
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-access-control.php b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-access-control.php
index 758a2e6..28ca451 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-access-control.php
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-access-control.php
@@ -104,6 +104,12 @@
                      'content' => $content);
 }
 
+if (isset($_GET['WINDOW'])) {
+  header('Content-Type: text/html');
+  echo "<!DOCTYPE html><script>window.opener.postMessage('Loaded', '*');</script>";
+  exit;
+}
+
 header('Content-Type: application/json');
 $arr = array('jsonpResult' => 'success',
              'method' => $_SERVER['REQUEST_METHOD'],
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt
index 5dcde08..c219fb3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/access-control-and-redirects-async-expected.txt
@@ -1,6 +1,5 @@
 CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' to 'http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.
 CONSOLE WARNING: Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are deprecated, and will be blocked in M59, around June 2017. See https://www.chromestatus.com/feature/5669008342777856 for more details.
-CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000' has been blocked by CORS policy: Redirect location 'http://username:password@localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi' contains a username and password, which is disallowed for cross-origin requests.
 CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=foo://bar.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000. Redirect from 'http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?url=foo://bar.cgi&%20%20access-control-allow-origin=http://127.0.0.1:8000' has been blocked by CORS policy: Redirect location 'foo://bar.cgi' has a disallowed scheme for cross-origin requests.
 CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/redirect-cors.php?redirect-preflight=true&%20%20url=http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi&%20%20access-control-allow-origin=*. Response for preflight is invalid (redirect)
 CONSOLE ERROR: XMLHttpRequest cannot load http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi. Request header field x-webkit is not allowed by Access-Control-Allow-Headers in preflight response.
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/failed-auth-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/failed-auth-expected.txt
index ce349cd..1e8a2865 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/failed-auth-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/failed-auth-expected.txt
@@ -1,8 +1,8 @@
-CONSOLE WARNING: line 30: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE WARNING: line 40: Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are deprecated, and will be blocked in M59, around June 2017. See https://www.chromestatus.com/feature/5669008342777856 for more details.
+CONSOLE WARNING: line 35: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
+CONSOLE WARNING: line 45: Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are deprecated, and will be blocked in M59, around June 2017. See https://www.chromestatus.com/feature/5669008342777856 for more details.
 Test for bug 13075: XMLHttpRequest with failed authentication should set status to 401.
 
 Sync, no credentials: OK
-Sync, incorrect credentials: OK
+Sync, incorrect credentials: NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://badname:passpw@127.0.0.1:8000/xmlhttprequest/resources/basic-auth/basic-auth.php?uid=login2'.
 Async, no credentials: OK
 Async, incorrect credentials: OK
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/failed-auth.html b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/failed-auth.html
index b16e4991..c6b555e3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/failed-auth.html
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/failed-auth.html
@@ -12,6 +12,11 @@
         ((code == 401) ? " OK" : (" " + code + " != 401"));
 }
 
+function checkFailure(n, code) {
+    document.getElementsByTagName("li")[n - 1].firstChild.nodeValue += 
+        ((code == 0) ? " OK" : (" " + code + " != 0"));
+}
+
 function log(n, message) {
     document.getElementsByTagName("li")[n - 1].firstChild.nodeValue += 
         " " + message;
@@ -64,7 +69,7 @@
         r.open("GET", "resources/basic-auth/basic-auth.php?uid=login4", true, "badname", "passpw");
         r.onreadystatechange = function() {
           if (r.readyState == 4) {
-            checkResult(4, r.status);
+            checkFailure(4, r.status);
             testRunner.notifyDone();
           }
         };
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/logout-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/logout-expected.txt
deleted file mode 100644
index aacb566..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/logout-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-CONSOLE WARNING: line 17: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE WARNING: line 18: Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are deprecated, and will be blocked in M59, around June 2017. See https://www.chromestatus.com/feature/5669008342777856 for more details.
-rdar://problem/6447115 Test that a method for logging out of a site that is used by SAP works.
-
-If an authentication dialog appears, please cancel it.
-
-Login: PASS
-Async request sent before logout: PASS
-Logout: FAIL
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/logout.html b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/logout.html
deleted file mode 100644
index e20b3d79..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/logout.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<body>
-<p><a href="rdar://problem/6447115">rdar://problem/6447115</a> Test that a method for logging out of a site that is used by SAP works.</p>
-<p>If an authentication dialog appears, please cancel it.</p>
-<span>Login: </span><span id="login">FAIL - Test not run</span><br>
-<span>Async request sent before logout: </span><span id="async">FAIL - Test not run</span><br>
-<span>Logout: </span><span id="logout">FAIL - Test not run</span>
-<script>
-if (window.testRunner) {
-    testRunner.dumpAsText();
-    testRunner.waitUntilDone();
-}
-
-function login()
-{
-    var xhr = new XMLHttpRequest;
-    // "?login" is only here for ease of debugging; it doesn't affect behavior.
-    xhr.open("GET", "resources/logout/resource.php?login", false, "user", "pass");
-    xhr.send("");
-}
-
-function logout()
-{
-    var xhr = new XMLHttpRequest;
-    // logout.html doesn't even exist - we don't need to send this request to server.
-    xhr.open("GET", "resources/logout/subdirectory/logout.html", true, "logout", "logout");
-    xhr.send("");
-    xhr.abort();
-}
-
-function isAuthenticated()
-{
-    var xhr = new XMLHttpRequest;
-    // "?isAuthenticated" is only here for ease of debugging; it doesn't affect behavior.
-    xhr.open("GET", "resources/logout/resource.php?isAuthenticated", false);
-    xhr.send("");
-    return xhr.status == 200;
-}
-
-login();
-document.getElementById("login").innerHTML = isAuthenticated() ? "PASS" : "FAIL";
-
-// Test that a request sent before logout actually has credentials.
-var r = new XMLHttpRequest;
-r.open("GET", "resources/logout/resource.php?isAuthenticated2", true);
-r.onload = function() {
-    document.getElementById("async").innerHTML = r.status == 200 ? "PASS" : "FAIL";
-
-    if (window.testRunner)
-        testRunner.notifyDone();
-}
-r.send("");
-
-logout();
-document.getElementById("logout").innerHTML = isAuthenticated() ? "FAIL" : "PASS";
-</script>
-</body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/null-auth-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/null-auth-expected.txt
index 127444c..3a3465de 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/null-auth-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/null-auth-expected.txt
@@ -1,7 +1,8 @@
-CONSOLE WARNING: line 9: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE WARNING: line 10: Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are deprecated, and will be blocked in M59, around June 2017. See https://www.chromestatus.com/feature/5669008342777856 for more details.
+CONSOLE WARNING: line 10: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
+CONSOLE WARNING: line 11: Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are deprecated, and will be blocked in M59, around June 2017. See https://www.chromestatus.com/feature/5669008342777856 for more details.
+CONSOLE MESSAGE: line 14: Pass: credentialed URL threw.
 Test that null values in XHR login/password parameters are treated correctly.
 
 No auth tokens should be sent with this request.
 
-No authentication
+ 
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/null-auth.php b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/null-auth.php
index 2965c95..7ee1e71 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/null-auth.php
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/null-auth.php
@@ -5,8 +5,12 @@
 if (window.testRunner)
   testRunner.dumpAsText();
 
-req = new XMLHttpRequest;
-req.open('POST', '<?php echo 'http://foo:bar@' . $_SERVER['HTTP_HOST'] . '/xmlhttprequest/resources/echo-auth.php' ?>', false, null, null);
-req.send();
-document.getElementById('syncResult').firstChild.nodeValue = req.responseText;
+try {
+  req = new XMLHttpRequest;
+  req.open('POST', '<?php echo 'http://foo:bar@' . $_SERVER['HTTP_HOST'] . '/xmlhttprequest/resources/echo-auth.php' ?>', false, null, null);
+  req.send();
+  console.log("Fail: credentialed URLs should throw.");
+} catch (e) {
+  console.log("Pass: credentialed URL threw.");
+}
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/remember-bad-password-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/remember-bad-password-expected.txt
deleted file mode 100644
index dae7745..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/remember-bad-password-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-CONSOLE WARNING: line 53: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE WARNING: line 23: Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are deprecated, and will be blocked in M59, around June 2017. See https://www.chromestatus.com/feature/5669008342777856 for more details.
-rdar://problem/7062824 A wrong password entered for site or proxy auth remains in WebCore credential storage, and is sent with subsequent requests.
-
-This test counts the number of failed requests server side.
-
-PASS
-
-Sync
-With credentials Without credentials
-Async
-With credentials Without credentials 
-Status
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/remember-bad-password.html b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/remember-bad-password.html
deleted file mode 100644
index f15da260..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/remember-bad-password.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<body>
-<p><a href="rdar://problem/7062824">rdar://problem/7062824</a> A wrong password entered for site or proxy auth remains in WebCore credential storage, and is sent with subsequent requests.</p>
-<p>This test counts the number of failed requests server side.</p>
-<div id = result>Testing... Please cancel all authentication dialogs.</div></br>
-<div>Sync</div>
-<button onclick="sendWithCredentials(false)">With credentials</button>
-<button onclick="sendWithoutCredentials(false)">Without credentials</button>
-<div>Async</div>
-<button onclick="sendWithCredentials(true)">With credentials</button>
-<button onclick="sendWithoutCredentials(true)">Without credentials</button>
-<br>
-<button onclick="status()">Status</button>
-<script>
-if (window.testRunner) {
-    testRunner.dumpAsText();
-    testRunner.waitUntilDone()
-}
-
-function sendWithCredentials(next)
-{
-    var xhr = new XMLHttpRequest;
-    xhr.open("GET", "resources/remember-bad-password/count-failures.php", next ? true : false, "foo", "bar");
-    xhr.send("");
-    if (next) {
-        xhr.onload = next;
-        xhr.onerror = next;
-    }
-}
-
-function sendWithoutCredentials(next)
-{
-    var xhr = new XMLHttpRequest;
-    xhr.open("GET", "resources/remember-bad-password/count-failures.php", next ? true : false);
-    xhr.send("");
-
-    if (next) {
-        xhr.onload = next;
-        xhr.onerror = next;
-    }
-}
-
-function status()
-{
-    var xhr = new XMLHttpRequest;
-    xhr.open("GET", "resources/remember-bad-password/count-failures.php?command=status", false);
-    xhr.send("");
-    return xhr.responseText;
-}
-
-function reset()
-{
-    var xhr = new XMLHttpRequest;
-    xhr.open("GET", "resources/remember-bad-password/count-failures.php?command=reset", false);
-    xhr.send("");
-}
-
-reset();
-sendWithCredentials();
-sendWithoutCredentials();
-sendWithCredentials(function() {
-sendWithoutCredentials(function() {
-var s = status();
-document.getElementById("result").innerHTML = (s == 2 ? "PASS" : ("FAIL: " + s));
-if (window.testRunner)
-    testRunner.notifyDone();
-})});
-</script>
-</body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/referer-expected.txt b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/referer-expected.txt
index 29b4e33..040d2f4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/referer-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/referer-expected.txt
@@ -1,4 +1,3 @@
-CONSOLE WARNING: line 3: Subresource requests whose URLs contain embedded credentials (e.g. `https://user:pass@host/`) are deprecated, and will be blocked in M59, around June 2017. See https://www.chromestatus.com/feature/5669008342777856 for more details.
 Referer should be set for XMLHttpRequest from Workers.
 
 PASS: Sync referer.
diff --git a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/resources/referer-test.js b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/resources/referer-test.js
index 599e870..ad1c542d 100644
--- a/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/resources/referer-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/xmlhttprequest/workers/resources/referer-test.js
@@ -13,7 +13,7 @@
     console_messages.appendChild(item);
 }
 
-var workerUrl = location.protocol + "//MyUserName:MySecurePassword@" + location.host + location.pathname.replace(/\/[^\/]*$/, "") + '/resources/referer.js#ref';
+var workerUrl = location.protocol + "//" + location.host + location.pathname.replace(/\/[^\/]*$/, "") + '/resources/referer.js#ref';
 var worker = createWorker(workerUrl);
 
 worker.onmessage = function(evt)
diff --git a/third_party/WebKit/LayoutTests/mojo/module-loading.html b/third_party/WebKit/LayoutTests/mojo/module-loading.html
deleted file mode 100644
index 6ebd60e..0000000
--- a/third_party/WebKit/LayoutTests/mojo/module-loading.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<title>Mojo JavaScript bindings module loading tests</title>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="file:///gen/mojo/public/js/mojo_bindings.js"></script>
-<script src="file:///gen/mojo/public/interfaces/bindings/tests/echo_import.mojom.js"></script>
-<script src="file:///gen/mojo/public/interfaces/bindings/tests/echo.mojom.js"></script>
-<script>
-
-promise_test(async () => {
-  function EchoImpl() {}
-  EchoImpl.prototype.echoPoint = function(point) {
-    return Promise.resolve({result: point});
-  };
-
-  var echoServicePtr = new test.echo.mojom.EchoPtr();
-  var echoServiceBinding = new mojoBindings.Binding(
-      test.echo.mojom.Echo,
-      new EchoImpl(),
-      mojoBindings.makeRequest(echoServicePtr));
-  var result = (await echoServicePtr.echoPoint({x: 1, y: 2})).result;
-  assert_equals(1, result.x);
-  assert_equals(2, result.y);
-}, 'Basics');
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/sensor/absolute-orientation-sensor.html b/third_party/WebKit/LayoutTests/sensor/absolute-orientation-sensor.html
new file mode 100644
index 0000000..3667924
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/sensor/absolute-orientation-sensor.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="../resources/mojo-helpers.js"></script>
+<script src="resources/sensor-helpers.js"></script>
+<script src="resources/generic-sensor-tests.js"></script>
+<script>
+
+'use strict';
+
+if (!window.testRunner)
+    debug('This test cannot be run without the TestRunner');
+
+const kQuaternion = [0, 1, 0, 0]; // 180 degrees around X axis.
+const kRotationMatrix = [1,  0,  0,  0,
+                         0, -1,  0,  0,
+                         0,  0, -1,  0,
+                         0,  0,  0,  1];
+
+function update_sensor_reading(buffer, expects_modified_reading, readsCount) {
+  buffer[1] = window.performance.now();
+  buffer[2] = 1;
+  buffer[3] = 0;
+  buffer[4] = 0;
+  buffer[5] = 0;
+}
+
+function verify_sensor_reading(sensor, should_be_null) {
+  if (should_be_null)
+    return sensor.quaternion == null && sensor.timestamp == null;
+
+  if (sensor.timestamp == null ||
+      sensor.quaternion.toString() != kQuaternion.toString())
+    return false;
+
+  let rotationMatrix = new Float32Array(16);
+  sensor.populateMatrix(rotationMatrix);
+  return rotationMatrix.toString() == kRotationMatrix.toString();
+}
+
+runGenericSensorTests(AbsoluteOrientationSensor, update_sensor_reading, verify_sensor_reading);
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/sensor/idl-AbsoluteOrientationSensor.html b/third_party/WebKit/LayoutTests/sensor/idl-AbsoluteOrientationSensor.html
new file mode 100644
index 0000000..8f31d79c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/sensor/idl-AbsoluteOrientationSensor.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script>
+
+test(function() {
+  // Test that AbsoluteOrientationSensor interface exists
+  assert_true('AbsoluteOrientationSensor' in window);
+}, 'Test that the AbsoluteOrientationSensor interface is present.');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 0b8239f2..95f2c62 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -5,6 +5,9 @@
 
 
 [INTERFACES]
+interface AbsoluteOrientationSensor : OrientationSensor
+    attribute @@toStringTag
+    method constructor
 interface Accelerometer : Sensor
     attribute @@toStringTag
     getter includesGravity
@@ -4582,6 +4585,11 @@
     setter selected
     setter text
     setter value
+interface OrientationSensor : Sensor
+    attribute @@toStringTag
+    getter quaternion
+    method constructor
+    method populateMatrix
 interface OscillatorNode : AudioScheduledSourceNode
     attribute @@toStringTag
     getter detune
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp
index da5d183..d1f4851 100644
--- a/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/serialization/SerializedScriptValueFuzzer.cpp
@@ -75,9 +75,8 @@
   if (hash & kFuzzMessagePorts) {
     options.messagePorts = new MessagePortArray(3);
     std::generate(messagePorts->begin(), messagePorts->end(), []() {
-      WebMessagePortChannelUniquePtr channel(new WebMessagePortChannelImpl());
       MessagePort* port = MessagePort::create(pageHolder->document());
-      port->entangle(std::move(channel));
+      port->entangle(WTF::makeUnique<WebMessagePortChannelImpl>());
       return port;
     });
   }
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializerTest.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializerTest.cpp
index fd6a50c0..60a2658 100644
--- a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializerTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializerTest.cpp
@@ -267,13 +267,15 @@
 MessagePort* makeMessagePort(
     ExecutionContext* executionContext,
     WebMessagePortChannel** unownedChannelOut = nullptr) {
-  auto* unownedChannel = new WebMessagePortChannelImpl();
+  std::unique_ptr<WebMessagePortChannelImpl> channel =
+      WTF::makeUnique<WebMessagePortChannelImpl>();
+  auto* unownedChannelPtr = channel.get();
   MessagePort* port = MessagePort::create(*executionContext);
-  port->entangle(WebMessagePortChannelUniquePtr(unownedChannel));
+  port->entangle(std::move(channel));
   EXPECT_TRUE(port->isEntangled());
-  EXPECT_EQ(unownedChannel, port->entangledChannelForTesting());
+  EXPECT_EQ(unownedChannelPtr, port->entangledChannelForTesting());
   if (unownedChannelOut)
-    *unownedChannelOut = unownedChannel;
+    *unownedChannelOut = unownedChannelPtr;
   return port;
 }
 
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index 53be3ac..5a15807 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1382,7 +1382,6 @@
     "style/FilterOperationsTest.cpp",
     "style/OutlineValueTest.cpp",
     "style/SVGComputedStyleTest.cpp",
-    "style/StyleDifferenceTest.cpp",
     "svg/SVGPathParserTest.cpp",
     "svg/UnsafeSVGAttributeSanitizationTest.cpp",
     "svg/graphics/SVGImageTest.cpp",
diff --git a/third_party/WebKit/Source/core/dom/MessageChannel.cpp b/third_party/WebKit/Source/core/dom/MessageChannel.cpp
index 4e6c935..4094430 100644
--- a/third_party/WebKit/Source/core/dom/MessageChannel.cpp
+++ b/third_party/WebKit/Source/core/dom/MessageChannel.cpp
@@ -33,15 +33,15 @@
 namespace blink {
 
 static void createChannel(MessagePort* port1, MessagePort* port2) {
-  WebMessagePortChannel* channel1;
-  WebMessagePortChannel* channel2;
+  std::unique_ptr<WebMessagePortChannel> channel1;
+  std::unique_ptr<WebMessagePortChannel> channel2;
   Platform::current()->createMessageChannel(&channel1, &channel2);
   DCHECK(channel1);
   DCHECK(channel2);
 
   // Now entangle the proxies with the appropriate local ports.
-  port1->entangle(WebMessagePortChannelUniquePtr(channel2));
-  port2->entangle(WebMessagePortChannelUniquePtr(channel1));
+  port1->entangle(std::move(channel2));
+  port2->entangle(std::move(channel1));
 }
 
 MessageChannel::MessageChannel(ExecutionContext* context)
diff --git a/third_party/WebKit/Source/core/dom/MessagePort.cpp b/third_party/WebKit/Source/core/dom/MessagePort.cpp
index 4e4a711..c84df15 100644
--- a/third_party/WebKit/Source/core/dom/MessagePort.cpp
+++ b/third_party/WebKit/Source/core/dom/MessagePort.cpp
@@ -108,7 +108,7 @@
   return MessagePort::entanglePorts(*context, std::move(channels));
 }
 
-WebMessagePortChannelUniquePtr MessagePort::disentangle() {
+std::unique_ptr<WebMessagePortChannel> MessagePort::disentangle() {
   DCHECK(m_entangledChannel);
   m_entangledChannel->setClient(nullptr);
   return std::move(m_entangledChannel);
@@ -152,7 +152,7 @@
   m_closed = true;
 }
 
-void MessagePort::entangle(WebMessagePortChannelUniquePtr remote) {
+void MessagePort::entangle(std::unique_ptr<WebMessagePortChannel> remote) {
   // Only invoked to set our initial entanglement.
   DCHECK(!m_entangledChannel);
   DCHECK(getExecutionContext());
diff --git a/third_party/WebKit/Source/core/dom/MessagePort.h b/third_party/WebKit/Source/core/dom/MessagePort.h
index dcca8c6..5ba4dcc2 100644
--- a/third_party/WebKit/Source/core/dom/MessagePort.h
+++ b/third_party/WebKit/Source/core/dom/MessagePort.h
@@ -48,9 +48,8 @@
 class ScriptState;
 class SerializedScriptValue;
 
-// Not to be confused with WebMessagePortChannelArray; this one uses Vector and
-// std::unique_ptr instead of WebVector and raw pointers.
-typedef Vector<WebMessagePortChannelUniquePtr, 1> MessagePortChannelArray;
+typedef Vector<std::unique_ptr<WebMessagePortChannel>, 1>
+    MessagePortChannelArray;
 
 class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
                                 public ActiveScriptWrappable<MessagePort>,
@@ -72,8 +71,8 @@
   void start();
   void close();
 
-  void entangle(WebMessagePortChannelUniquePtr);
-  WebMessagePortChannelUniquePtr disentangle();
+  void entangle(std::unique_ptr<WebMessagePortChannel>);
+  std::unique_ptr<WebMessagePortChannel> disentangle();
 
   static WebMessagePortChannelArray toWebMessagePortChannelArray(
       MessagePortChannelArray);
@@ -139,7 +138,7 @@
   void messageAvailable() override;
   void dispatchMessages();
 
-  WebMessagePortChannelUniquePtr m_entangledChannel;
+  std::unique_ptr<WebMessagePortChannel> m_entangledChannel;
 
   int m_pendingDispatchTask;
   bool m_started;
diff --git a/third_party/WebKit/Source/core/editing/SelectionController.cpp b/third_party/WebKit/Source/core/editing/SelectionController.cpp
index de2efb5..267308f 100644
--- a/third_party/WebKit/Source/core/editing/SelectionController.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionController.cpp
@@ -709,6 +709,12 @@
                 PositionInFlatTree::firstPositionInOrBeforeNode(innerNode))
           : visibleHitPos;
 
+  if (visiblePos.isNull()) {
+    updateSelectionForMouseDownDispatchingSelectStart(
+        innerNode, VisibleSelectionInFlatTree(), CharacterGranularity,
+        HandleVisibility::Visible);
+    return;
+  }
   updateSelectionForMouseDownDispatchingSelectStart(
       innerNode,
       expandSelectionToRespectUserSelectAll(
diff --git a/third_party/WebKit/Source/core/editing/SelectionControllerTest.cpp b/third_party/WebKit/Source/core/editing/SelectionControllerTest.cpp
index a8e0c22..3ce31df9c 100644
--- a/third_party/WebKit/Source/core/editing/SelectionControllerTest.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionControllerTest.cpp
@@ -24,6 +24,7 @@
     return selection().selectionInFlatTree();
   }
 
+  void setCaretAtHitTestResult(const HitTestResult&);
   void setNonDirectionalSelectionIfNeeded(const SelectionInFlatTree&,
                                           TextGranularity);
 
@@ -31,6 +32,12 @@
   DISALLOW_COPY_AND_ASSIGN(SelectionControllerTest);
 };
 
+void SelectionControllerTest::setCaretAtHitTestResult(
+    const HitTestResult& hitTestResult) {
+  frame().eventHandler().selectionController().setCaretAtHitTestResult(
+      hitTestResult);
+}
+
 void SelectionControllerTest::setNonDirectionalSelectionIfNeeded(
     const SelectionInFlatTree& newSelection,
     TextGranularity granularity) {
@@ -104,4 +111,21 @@
       frame().eventHandler().hitTestResultAtPoint(IntPoint(8, 8)));
 }
 
+// For http://crbug.com/704827
+TEST_F(SelectionControllerTest, setCaretAtHitTestResultWithNullPosition) {
+  setBodyContent(
+      "<style>"
+      "#sample:before {content: '&nbsp;'}"
+      "#sample { user-select: none; }"
+      "</style>"
+      "<div id=sample></div>");
+  document().view()->updateAllLifecyclePhases();
+
+  // Hit "&nbsp;" in before pseudo element of "sample".
+  setCaretAtHitTestResult(
+      frame().eventHandler().hitTestResultAtPoint(IntPoint(10, 10)));
+
+  EXPECT_TRUE(selection().selectionInDOMTree().isNone());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameClient.h b/third_party/WebKit/Source/core/frame/LocalFrameClient.h
index 23adffc..771b8f0a 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrameClient.h
+++ b/third_party/WebKit/Source/core/frame/LocalFrameClient.h
@@ -284,7 +284,7 @@
       const String& headerValue,
       ContentSecurityPolicyHeaderType,
       ContentSecurityPolicyHeaderSource,
-      const std::vector<WebContentSecurityPolicyPolicy>&) {}
+      const std::vector<WebContentSecurityPolicy>&) {}
 
   virtual void didChangeFrameOwnerProperties(HTMLFrameElementBase*) {}
 
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
index 32a338f..86366e3 100644
--- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
@@ -1320,9 +1320,8 @@
   return m_pluginTypes->subsumes(pluginTypesOther);
 }
 
-WebContentSecurityPolicyPolicy CSPDirectiveList::exposeForNavigationalChecks()
-    const {
-  WebContentSecurityPolicyPolicy policy;
+WebContentSecurityPolicy CSPDirectiveList::exposeForNavigationalChecks() const {
+  WebContentSecurityPolicy policy;
   policy.disposition = static_cast<WebContentSecurityPolicyType>(m_headerType);
   policy.source = static_cast<WebContentSecurityPolicySource>(m_headerSource);
   std::vector<WebContentSecurityPolicyDirective> directives;
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h
index e701cb9..53ae94b 100644
--- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h
+++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h
@@ -175,7 +175,7 @@
   // * form-action
   // The exported directives only contains sources that affect navigation. For
   // instance it doesn't contains 'unsafe-inline' or 'unsafe-eval'
-  WebContentSecurityPolicyPolicy exposeForNavigationalChecks() const;
+  WebContentSecurityPolicy exposeForNavigationalChecks() const;
 
   DECLARE_TRACE();
 
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
index b924b89..913ef17 100644
--- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -349,7 +349,7 @@
     // when (2) is finished.
 
     // Zero, one or several policies could be produced by only one header.
-    std::vector<blink::WebContentSecurityPolicyPolicy> policies;
+    std::vector<blink::WebContentSecurityPolicy> policies;
     for (size_t i = previousPolicyCount; i < m_policies.size(); ++i)
       policies.push_back(m_policies[i]->exposeForNavigationalChecks());
     document()->frame()->client()->didAddContentSecurityPolicy(
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 6d117db..d21ed5f 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -800,6 +800,10 @@
       Deprecation::countDeprecation(
           frame()->document(),
           UseCounter::RequestedSubresourceWithEmbeddedCredentials);
+      // TODO(mkwst): Remove the runtime-enabled check in M59:
+      // https://www.chromestatus.com/feature/5669008342777856
+      if (RuntimeEnabledFeatures::blockCredentialedSubresourcesEnabled())
+        return ResourceRequestBlockedReason::Origin;
     }
   }
 
diff --git a/third_party/WebKit/Source/core/style/BUILD.gn b/third_party/WebKit/Source/core/style/BUILD.gn
index f7563bf..e9913a8 100644
--- a/third_party/WebKit/Source/core/style/BUILD.gn
+++ b/third_party/WebKit/Source/core/style/BUILD.gn
@@ -63,7 +63,6 @@
     "StyleContentAlignmentData.h",
     "StyleDeprecatedFlexibleBoxData.cpp",
     "StyleDeprecatedFlexibleBoxData.h",
-    "StyleDifference.cpp",
     "StyleDifference.h",
     "StyleFetchedImage.cpp",
     "StyleFetchedImage.h",
diff --git a/third_party/WebKit/Source/core/style/StyleDifference.cpp b/third_party/WebKit/Source/core/style/StyleDifference.cpp
deleted file mode 100644
index ec4d70e7..0000000
--- a/third_party/WebKit/Source/core/style/StyleDifference.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/style/StyleDifference.h"
-
-namespace blink {
-
-std::ostream& operator<<(std::ostream& out, const StyleDifference& diff) {
-  out << "StyleDifference{layoutType=";
-
-  switch (diff.m_layoutType) {
-    case StyleDifference::NoLayout:
-      out << "NoLayout";
-      break;
-    case StyleDifference::PositionedMovement:
-      out << "PositionedMovement";
-      break;
-    case StyleDifference::FullLayout:
-      out << "FullLayout";
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-
-  out << ", paintInvalidationType=";
-  switch (diff.m_paintInvalidationType) {
-    case StyleDifference::NoPaintInvalidation:
-      out << "NoPaintInvalidation";
-      break;
-    case StyleDifference::PaintInvalidationObject:
-      out << "PaintInvalidationObject";
-      break;
-    case StyleDifference::PaintInvalidationSubtree:
-      out << "PaintInvalidationSubtree";
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-
-  out << ", recomputeOverflow=" << diff.m_recomputeOverflow;
-  out << ", visualRectUpdate=" << diff.m_visualRectUpdate;
-
-  out << ", propertySpecificDifferences=";
-  int diffCount = 0;
-  for (int i = 0; i < StyleDifference::PropertyDifferenceMax; i++) {
-    unsigned bitTest = 1 << i;
-    if (diff.m_propertySpecificDifferences & bitTest) {
-      if (diffCount++ > 0)
-        out << "|";
-      switch (bitTest) {
-        case StyleDifference::TransformChanged:
-          out << "TransformChanged";
-          break;
-        case StyleDifference::OpacityChanged:
-          out << "OpacityChanged";
-          break;
-        case StyleDifference::ZIndexChanged:
-          out << "ZIndexChanged";
-          break;
-        case StyleDifference::FilterChanged:
-          out << "FilterChanged";
-          break;
-        case StyleDifference::BackdropFilterChanged:
-          out << "BackdropFilterChanged";
-          break;
-        case StyleDifference::CSSClipChanged:
-          out << "CSSClipChanged";
-          break;
-        case StyleDifference::TextDecorationOrColorChanged:
-          out << "TextDecorationOrColorChanged";
-          break;
-        case StyleDifference::ScrollAnchorDisablingPropertyChanged:
-          out << "ScrollAnchorDisablingPropertyChanged";
-          break;
-        default:
-          NOTREACHED();
-          break;
-      }
-    }
-  }
-
-  return out << "}";
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/style/StyleDifference.h b/third_party/WebKit/Source/core/style/StyleDifference.h
index faafb52d..b775695 100644
--- a/third_party/WebKit/Source/core/style/StyleDifference.h
+++ b/third_party/WebKit/Source/core/style/StyleDifference.h
@@ -5,8 +5,6 @@
 #ifndef StyleDifference_h
 #define StyleDifference_h
 
-#include <iosfwd>
-#include "core/CoreExport.h"
 #include "wtf/Allocator.h"
 #include "wtf/Assertions.h"
 
@@ -29,8 +27,6 @@
     ScrollAnchorDisablingPropertyChanged = 1 << 7,
     // If you add a value here, be sure to update the number of bits on
     // m_propertySpecificDifferences.
-
-    PropertyDifferenceMax = TextDecorationOrColorChanged
   };
 
   StyleDifference()
@@ -143,9 +139,6 @@
   }
 
  private:
-  friend CORE_EXPORT std::ostream& operator<<(std::ostream&,
-                                              const StyleDifference&);
-
   enum PaintInvalidationType {
     NoPaintInvalidation,
     PaintInvalidationObject,
@@ -160,8 +153,6 @@
   unsigned m_propertySpecificDifferences : 8;
 };
 
-CORE_EXPORT std::ostream& operator<<(std::ostream&, const StyleDifference&);
-
 }  // namespace blink
 
 #endif  // StyleDifference_h
diff --git a/third_party/WebKit/Source/core/style/StyleDifferenceTest.cpp b/third_party/WebKit/Source/core/style/StyleDifferenceTest.cpp
deleted file mode 100644
index 5fdb6ed..0000000
--- a/third_party/WebKit/Source/core/style/StyleDifferenceTest.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/style/StyleDifference.h"
-
-#include <sstream>
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-TEST(StyleDifferenceTest, StreamOutputDefault) {
-  std::stringstream stringStream;
-  StyleDifference diff;
-  stringStream << diff;
-  EXPECT_EQ(
-      "StyleDifference{layoutType=NoLayout, "
-      "paintInvalidationType=NoPaintInvalidation, recomputeOverflow=0, "
-      "visualRectUpdate=0, propertySpecificDifferences=}",
-      stringStream.str());
-}
-
-TEST(StyleDifferenceTest, StreamOutputAllFieldsMutated) {
-  std::stringstream stringStream;
-  StyleDifference diff;
-  diff.setNeedsPaintInvalidationObject();
-  diff.setNeedsPositionedMovementLayout();
-  diff.setNeedsRecomputeOverflow();
-  diff.setNeedsVisualRectUpdate();
-  diff.setTransformChanged();
-  diff.setScrollAnchorDisablingPropertyChanged();
-  stringStream << diff;
-  EXPECT_EQ(
-      "StyleDifference{layoutType=PositionedMovement, "
-      "paintInvalidationType=PaintInvalidationObject, recomputeOverflow=1, "
-      "visualRectUpdate=1, "
-      "propertySpecificDifferences=TransformChanged|"
-      "ScrollAnchorDisablingPropertyChanged|TransformChanged|"
-      "ScrollAnchorDisablingPropertyChanged}",
-      stringStream.str());
-}
-
-TEST(StyleDifferenceTest, StreamOutputSetAllProperties) {
-  std::stringstream stringStream;
-  StyleDifference diff;
-  diff.setTransformChanged();
-  diff.setOpacityChanged();
-  diff.setZIndexChanged();
-  diff.setFilterChanged();
-  diff.setBackdropFilterChanged();
-  diff.setCSSClipChanged();
-  diff.setTextDecorationOrColorChanged();
-  diff.setScrollAnchorDisablingPropertyChanged();
-  stringStream << diff;
-  EXPECT_EQ(
-      "StyleDifference{layoutType=NoLayout, "
-      "paintInvalidationType=NoPaintInvalidation, recomputeOverflow=0, "
-      "visualRectUpdate=0, "
-      "propertySpecificDifferences=TransformChanged|OpacityChanged|"
-      "ZIndexChanged|FilterChanged|BackdropFilterChanged|CSSClipChanged|"
-      "TextDecorationOrColorChanged|ScrollAnchorDisablingPropertyChanged|"
-      "TransformChanged|OpacityChanged|ZIndexChanged|FilterChanged|"
-      "BackdropFilterChanged|CSSClipChanged|TextDecorationOrColorChanged|"
-      "ScrollAnchorDisablingPropertyChanged}",
-      stringStream.str());
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/SharedWorker.cpp b/third_party/WebKit/Source/core/workers/SharedWorker.cpp
index 54aeb2c..d160575 100644
--- a/third_party/WebKit/Source/core/workers/SharedWorker.cpp
+++ b/third_party/WebKit/Source/core/workers/SharedWorker.cpp
@@ -63,7 +63,8 @@
 
   MessageChannel* channel = MessageChannel::create(context);
   worker->m_port = channel->port1();
-  WebMessagePortChannelUniquePtr remotePort = channel->port2()->disentangle();
+  std::unique_ptr<WebMessagePortChannel> remotePort =
+      channel->port2()->disentangle();
   DCHECK(remotePort);
 
   // We don't currently support nested workers, so workers can only be created
diff --git a/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h b/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h
index cc287d8..fe8d01d 100644
--- a/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h
+++ b/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h
@@ -51,7 +51,7 @@
   virtual ~SharedWorkerRepositoryClient() {}
 
   virtual void connect(SharedWorker*,
-                       WebMessagePortChannelUniquePtr,
+                       std::unique_ptr<WebMessagePortChannel>,
                        const KURL&,
                        const String& name) = 0;
 
diff --git a/third_party/WebKit/Source/modules/beacon/README.md b/third_party/WebKit/Source/modules/beacon/README.md
new file mode 100644
index 0000000..32cec22
--- /dev/null
+++ b/third_party/WebKit/Source/modules/beacon/README.md
@@ -0,0 +1,3 @@
+# Beacon
+
+This directory contains the implementation of [the Beacon API](https://w3c.github.io/beacon/).
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni
index 21b7c6c..7133f50 100644
--- a/third_party/WebKit/Source/modules/modules_idl_files.gni
+++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -228,10 +228,12 @@
                     "quota/StorageUsageCallback.idl",
                     "remoteplayback/RemotePlayback.idl",
                     "screen_orientation/ScreenOrientation.idl",
+                    "sensor/AbsoluteOrientationSensor.idl",
                     "sensor/Accelerometer.idl",
-                    "sensor/Gyroscope.idl",
                     "sensor/AmbientLightSensor.idl",
+                    "sensor/Gyroscope.idl",
                     "sensor/Magnetometer.idl",
+                    "sensor/OrientationSensor.idl",
                     "sensor/Sensor.idl",
                     "sensor/SensorErrorEvent.idl",
                     "serviceworkers/Client.idl",
diff --git a/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.cpp b/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.cpp
new file mode 100644
index 0000000..da07482
--- /dev/null
+++ b/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.cpp
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "modules/sensor/AbsoluteOrientationSensor.h"
+
+using device::mojom::blink::SensorType;
+
+namespace blink {
+
+AbsoluteOrientationSensor* AbsoluteOrientationSensor::create(
+    ExecutionContext* executionContext,
+    const SensorOptions& options,
+    ExceptionState& exceptionState) {
+  return new AbsoluteOrientationSensor(executionContext, options,
+                                       exceptionState);
+}
+
+// static
+AbsoluteOrientationSensor* AbsoluteOrientationSensor::create(
+    ExecutionContext* executionContext,
+    ExceptionState& exceptionState) {
+  return create(executionContext, SensorOptions(), exceptionState);
+}
+
+AbsoluteOrientationSensor::AbsoluteOrientationSensor(
+    ExecutionContext* executionContext,
+    const SensorOptions& options,
+    ExceptionState& exceptionState)
+    : OrientationSensor(executionContext,
+                        options,
+                        exceptionState,
+                        SensorType::ABSOLUTE_ORIENTATION) {}
+
+DEFINE_TRACE(AbsoluteOrientationSensor) {
+  OrientationSensor::trace(visitor);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.h b/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.h
new file mode 100644
index 0000000..18cdb9dd
--- /dev/null
+++ b/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.h
@@ -0,0 +1,31 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AbsoluteOrientationSensor_h
+#define AbsoluteOrientationSensor_h
+
+#include "modules/sensor/OrientationSensor.h"
+
+namespace blink {
+
+class AbsoluteOrientationSensor final : public OrientationSensor {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  static AbsoluteOrientationSensor* create(ExecutionContext*,
+                                           const SensorOptions&,
+                                           ExceptionState&);
+  static AbsoluteOrientationSensor* create(ExecutionContext*, ExceptionState&);
+
+  DECLARE_VIRTUAL_TRACE();
+
+ private:
+  AbsoluteOrientationSensor(ExecutionContext*,
+                            const SensorOptions&,
+                            ExceptionState&);
+};
+
+}  // namespace blink
+
+#endif  // AbsoluteOrientationSensor_h
diff --git a/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.idl b/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.idl
new file mode 100644
index 0000000..55421770
--- /dev/null
+++ b/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.idl
@@ -0,0 +1,14 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Specification at:
+// https://w3c.github.io/orientation-sensor/#absoluteorientationsensor-interface
+
+[
+    RuntimeEnabled=Sensor,
+    Constructor(optional SensorOptions sensorOptions),
+    ConstructorCallWith=ExecutionContext,
+    RaisesException=Constructor,
+] interface AbsoluteOrientationSensor : OrientationSensor {
+};
diff --git a/third_party/WebKit/Source/modules/sensor/BUILD.gn b/third_party/WebKit/Source/modules/sensor/BUILD.gn
index e7eac6e..ae8ffaed 100644
--- a/third_party/WebKit/Source/modules/sensor/BUILD.gn
+++ b/third_party/WebKit/Source/modules/sensor/BUILD.gn
@@ -6,6 +6,8 @@
 
 blink_modules_sources("sensor") {
   sources = [
+    "AbsoluteOrientationSensor.cpp",
+    "AbsoluteOrientationSensor.h",
     "Accelerometer.cpp",
     "Accelerometer.h",
     "AmbientLightSensor.cpp",
@@ -14,6 +16,8 @@
     "Gyroscope.h",
     "Magnetometer.cpp",
     "Magnetometer.h",
+    "OrientationSensor.cpp",
+    "OrientationSensor.h",
     "Sensor.cpp",
     "Sensor.h",
     "SensorErrorEvent.cpp",
diff --git a/third_party/WebKit/Source/modules/sensor/OrientationSensor.cpp b/third_party/WebKit/Source/modules/sensor/OrientationSensor.cpp
new file mode 100644
index 0000000..7a4ea24
--- /dev/null
+++ b/third_party/WebKit/Source/modules/sensor/OrientationSensor.cpp
@@ -0,0 +1,75 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "modules/sensor/OrientationSensor.h"
+
+#include "bindings/core/v8/ExceptionState.h"
+
+using device::mojom::blink::SensorType;
+
+namespace blink {
+
+Vector<double> OrientationSensor::quaternion(bool& isNull) {
+  m_readingDirty = false;
+  isNull = !canReturnReadings();
+  return isNull ? Vector<double>()
+                : Vector<double>({readingValueUnchecked(3),    // W
+                                  readingValueUnchecked(0),    // Vx
+                                  readingValueUnchecked(1),    // Vy
+                                  readingValueUnchecked(2)});  // Vz
+}
+
+void OrientationSensor::populateMatrix(DOMFloat32Array* buffer,
+                                       ExceptionState& exceptionState) {
+  if (buffer->length() < 16) {
+    exceptionState.throwTypeError(
+        "Target buffer must have at least 16 elements.");
+    return;
+  }
+  if (!isActivated()) {
+    exceptionState.throwDOMException(
+        InvalidStateError, "The sensor must be in 'connected' state.");
+    return;
+  }
+  if (!canReturnReadings())
+    return;
+
+  float x = readingValueUnchecked(0);
+  float y = readingValueUnchecked(1);
+  float z = readingValueUnchecked(2);
+  float w = readingValueUnchecked(3);
+
+  float* out = buffer->data();
+  out[0] = 1.0 - 2 * (y * y - z * z);
+  out[1] = 2 * (x * y - z * w);
+  out[2] = 2 * (x * z + y * w);
+  out[4] = 2 * (x * y + z * w);
+  out[5] = 1.0 - 2 * (x * x - z * z);
+  out[6] = 2 * (y * z - x * w);
+  out[8] = 2 * (x * z - y * w);
+  out[9] = 2 * (y * z + x * w);
+  out[10] = 1.0 - 2 * (x * x - y * y);
+  out[15] = 1.0;
+}
+
+bool OrientationSensor::isReadingDirty() const {
+  return m_readingDirty || !canReturnReadings();
+}
+
+OrientationSensor::OrientationSensor(ExecutionContext* executionContext,
+                                     const SensorOptions& options,
+                                     ExceptionState& exceptionState,
+                                     device::mojom::blink::SensorType type)
+    : Sensor(executionContext, options, exceptionState, type),
+      m_readingDirty(true) {}
+
+void OrientationSensor::onSensorReadingChanged() {
+  m_readingDirty = true;
+}
+
+DEFINE_TRACE(OrientationSensor) {
+  Sensor::trace(visitor);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/sensor/OrientationSensor.h b/third_party/WebKit/Source/modules/sensor/OrientationSensor.h
new file mode 100644
index 0000000..52c20a7
--- /dev/null
+++ b/third_party/WebKit/Source/modules/sensor/OrientationSensor.h
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef OrientationSensor_h
+#define OrientationSensor_h
+
+#include "core/dom/DOMTypedArray.h"
+#include "modules/sensor/Sensor.h"
+
+namespace blink {
+
+class OrientationSensor : public Sensor {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  Vector<double> quaternion(bool& isNull);
+  void populateMatrix(DOMFloat32Array*, ExceptionState&);
+
+  bool isReadingDirty() const;
+
+  DECLARE_VIRTUAL_TRACE();
+
+ protected:
+  OrientationSensor(ExecutionContext*,
+                    const SensorOptions&,
+                    ExceptionState&,
+                    device::mojom::blink::SensorType);
+
+ private:
+  // SensorProxy override.
+  void onSensorReadingChanged() override;
+
+  bool m_readingDirty;
+};
+
+}  // namespace blink
+
+#endif  // OrientationSensor_h
diff --git a/third_party/WebKit/Source/modules/sensor/OrientationSensor.idl b/third_party/WebKit/Source/modules/sensor/OrientationSensor.idl
new file mode 100644
index 0000000..98692644
--- /dev/null
+++ b/third_party/WebKit/Source/modules/sensor/OrientationSensor.idl
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Specification at:
+// https://w3c.github.io/orientation-sensor/
+
+[
+    RuntimeEnabled=Sensor,
+] interface OrientationSensor : Sensor {
+    [CachedAttribute=isReadingDirty] readonly attribute FrozenArray<double>? quaternion;
+    [RaisesException] void populateMatrix(Float32Array targetBuffer);
+};
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.cpp b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
index c864dda..d470616 100644
--- a/third_party/WebKit/Source/modules/sensor/Sensor.cpp
+++ b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
@@ -163,10 +163,11 @@
 }
 
 double Sensor::readingValue(int index, bool& isNull) const {
-  if (!canReturnReadings()) {
-    isNull = true;
-    return 0.0;
-  }
+  isNull = !canReturnReadings();
+  return isNull ? 0.0 : readingValueUnchecked(index);
+}
+
+double Sensor::readingValueUnchecked(int index) const {
   DCHECK(m_sensorProxy);
   DCHECK(index >= 0 && index < device::SensorReading::kValuesCount);
   return m_sensorProxy->reading().values[index];
@@ -200,12 +201,13 @@
   startListening();
 }
 
-void Sensor::onSensorReadingChanged(double timestamp) {
+void Sensor::notifySensorChanged(double timestamp) {
   if (m_state != Sensor::SensorState::Activated)
     return;
 
   DCHECK_GT(m_configuration->frequency, 0.0);
   double period = 1 / m_configuration->frequency;
+
   if (timestamp - m_lastUpdateTimestamp >= period) {
     m_lastUpdateTimestamp = timestamp;
     notifySensorReadingChanged();
@@ -318,7 +320,7 @@
 }
 
 bool Sensor::canReturnReadings() const {
-  if (m_state != Sensor::SensorState::Activated)
+  if (!isActivated())
     return false;
   DCHECK(m_sensorProxy);
   return m_sensorProxy->reading().timestamp != 0.0;
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.h b/third_party/WebKit/Source/modules/sensor/Sensor.h
index 10bddba..e420d2d3 100644
--- a/third_party/WebKit/Source/modules/sensor/Sensor.h
+++ b/third_party/WebKit/Source/modules/sensor/Sensor.h
@@ -73,7 +73,11 @@
   // concrete sensor implementations can override this method to handle other
   // parameters if needed.
   virtual SensorConfigurationPtr createSensorConfig();
+
   double readingValue(int index, bool& isNull) const;
+  double readingValueUnchecked(int index) const;
+  bool canReturnReadings() const;
+  bool isActivated() const { return m_state == SensorState::Activated; }
 
  private:
   void initSensorProxyIfNeeded();
@@ -81,9 +85,9 @@
   // ContextLifecycleObserver overrides.
   void contextDestroyed(ExecutionContext*) override;
 
-  // SensorController::Observer overrides.
+  // SensorProxy::Observer overrides.
   void onSensorInitialized() override;
-  void onSensorReadingChanged(double timestamp) override;
+  void notifySensorChanged(double timestamp) override;
   void onSensorError(ExceptionCode,
                      const String& sanitizedMessage,
                      const String& unsanitizedMessage) override;
@@ -103,8 +107,6 @@
   void notifyOnActivate();
   void notifyError(DOMException* error);
 
-  bool canReturnReadings() const;
-
  private:
   SensorOptions m_sensorOptions;
   device::mojom::blink::SensorType m_type;
diff --git a/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp b/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp
index baa7be2..ea0a919 100644
--- a/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp
+++ b/third_party/WebKit/Source/modules/sensor/SensorProxy.cpp
@@ -129,7 +129,11 @@
     }
   }
 
-  m_reading = readingData;
+  if (m_reading.timestamp != readingData.timestamp) {
+    m_reading = readingData;
+    for (Observer* observer : m_observers)
+      observer->onSensorReadingChanged();
+  }
 }
 
 void SensorProxy::notifySensorChanged(double timestamp) {
@@ -137,7 +141,7 @@
   // we must cache m_observers as it can be modified within event handlers.
   auto copy = m_observers;
   for (Observer* observer : copy)
-    observer->onSensorReadingChanged(timestamp);
+    observer->notifySensorChanged(timestamp);
 }
 
 void SensorProxy::RaiseError() {
diff --git a/third_party/WebKit/Source/modules/sensor/SensorProxy.h b/third_party/WebKit/Source/modules/sensor/SensorProxy.h
index 65baab79..b911135 100644
--- a/third_party/WebKit/Source/modules/sensor/SensorProxy.h
+++ b/third_party/WebKit/Source/modules/sensor/SensorProxy.h
@@ -36,13 +36,20 @@
     // Has valid 'Sensor' binding, {add, remove}Configuration()
     // methods can be called.
     virtual void onSensorInitialized() {}
-    // Platfrom sensort reading has changed.
+    // Platfrom sensor reading has changed.
+    virtual void onSensorReadingChanged() {}
+    // Observer should send 'onchange' event if needed.
+    // The 'notifySensorChanged' calls are in sync with rAF.
+    // Currently, we decide whether to send 'onchange' event based on the
+    // time elapsed from the previous notification.
+    // TODO: Reconsider this after https://github.com/w3c/sensors/issues/152
+    // is resolved.
     // |timestamp| Reference timestamp in seconds of the moment when
     // sensor reading was updated from the buffer.
     // Note: |timestamp| values are only used to calculate elapsed time
     // between shared buffer readings. These values *do not* correspond
     // to sensor reading timestamps which are obtained on platform side.
-    virtual void onSensorReadingChanged(double timestamp) {}
+    virtual void notifySensorChanged(double timestamp) {}
     // An error has occurred.
     virtual void onSensorError(ExceptionCode,
                                const String& sanitizedMessage,
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index 7612fa9..a109094 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -1007,6 +1007,10 @@
       status: "experimental",
     },
     {
+      name: "BlockCredentialedSubresources",
+      status: "experimental",
+    },
+    {
       name: "UnclosedFormControlIsInvalid",
       status: "experimental",
     },
diff --git a/third_party/WebKit/Source/platform/exported/WebServiceWorkerRequest.cpp b/third_party/WebKit/Source/platform/exported/WebServiceWorkerRequest.cpp
index de10d81d..0edbaf7 100644
--- a/third_party/WebKit/Source/platform/exported/WebServiceWorkerRequest.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebServiceWorkerRequest.cpp
@@ -55,7 +55,7 @@
   m_private->m_url = url;
 }
 
-WebURL WebServiceWorkerRequest::url() const {
+const WebURL& WebServiceWorkerRequest::url() const {
   return m_private->m_url;
 }
 
@@ -63,7 +63,7 @@
   m_private->m_method = method;
 }
 
-WebString WebServiceWorkerRequest::method() const {
+const WebString& WebServiceWorkerRequest::method() const {
   return m_private->m_method;
 }
 
@@ -183,7 +183,7 @@
   m_private->m_clientId = clientId;
 }
 
-WebString WebServiceWorkerRequest::clientId() const {
+const WebString& WebServiceWorkerRequest::clientId() const {
   return m_private->m_clientId;
 }
 
diff --git a/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp b/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp
index 5d9e25b..cbaad22c 100644
--- a/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp
@@ -64,7 +64,7 @@
   m_private->statusText = statusText;
 }
 
-WebString WebServiceWorkerResponse::statusText() const {
+const WebString& WebServiceWorkerResponse::statusText() const {
   return m_private->statusText;
 }
 
@@ -132,7 +132,7 @@
   m_private->streamURL = url;
 }
 
-WebURL WebServiceWorkerResponse::streamURL() const {
+const WebURL& WebServiceWorkerResponse::streamURL() const {
   return m_private->streamURL;
 }
 
@@ -157,7 +157,7 @@
   m_private->cacheStorageCacheName = cacheStorageCacheName;
 }
 
-WebString WebServiceWorkerResponse::cacheStorageCacheName() const {
+const WebString& WebServiceWorkerResponse::cacheStorageCacheName() const {
   return m_private->cacheStorageCacheName;
 }
 
@@ -166,7 +166,8 @@
   m_private->corsExposedHeaderNames = headerNames;
 }
 
-WebVector<WebString> WebServiceWorkerResponse::corsExposedHeaderNames() const {
+const WebVector<WebString>& WebServiceWorkerResponse::corsExposedHeaderNames()
+    const {
   return m_private->corsExposedHeaderNames;
 }
 
diff --git a/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp b/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp
index c1adc7364..c26177a 100644
--- a/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp
+++ b/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp
@@ -920,7 +920,7 @@
     const String& headerValue,
     ContentSecurityPolicyHeaderType type,
     ContentSecurityPolicyHeaderSource source,
-    const std::vector<WebContentSecurityPolicyPolicy>& policies) {
+    const std::vector<WebContentSecurityPolicy>& policies) {
   if (m_webFrame->client()) {
     m_webFrame->client()->didAddContentSecurityPolicy(
         headerValue, static_cast<WebContentSecurityPolicyType>(type),
diff --git a/third_party/WebKit/Source/web/LocalFrameClientImpl.h b/third_party/WebKit/Source/web/LocalFrameClientImpl.h
index a7481d05..66545a25 100644
--- a/third_party/WebKit/Source/web/LocalFrameClientImpl.h
+++ b/third_party/WebKit/Source/web/LocalFrameClientImpl.h
@@ -191,7 +191,7 @@
       const String& headerValue,
       ContentSecurityPolicyHeaderType,
       ContentSecurityPolicyHeaderSource,
-      const std::vector<WebContentSecurityPolicyPolicy>&) override;
+      const std::vector<WebContentSecurityPolicy>&) override;
   void didChangeFrameOwnerProperties(HTMLFrameElementBase*) override;
 
   void dispatchWillStartUsingPeerConnectionHandler(
diff --git a/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp b/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp
index 256070d..8383573 100644
--- a/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp
+++ b/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp
@@ -112,7 +112,7 @@
 
 void SharedWorkerRepositoryClientImpl::connect(
     SharedWorker* worker,
-    WebMessagePortChannelUniquePtr port,
+    std::unique_ptr<WebMessagePortChannel> port,
     const KURL& url,
     const String& name) {
   DCHECK(m_client);
@@ -145,7 +145,7 @@
       worker->getExecutionContext()->securityContext().addressSpace(),
       isSecureContext ? WebSharedWorkerCreationContextTypeSecure
                       : WebSharedWorkerCreationContextTypeNonsecure,
-      port.release(), std::move(listener));
+      std::move(port), std::move(listener));
 }
 
 void SharedWorkerRepositoryClientImpl::documentDetached(Document* document) {
diff --git a/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.h b/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.h
index 2b9a8f7..1b0e381 100644
--- a/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.h
+++ b/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.h
@@ -55,7 +55,7 @@
   ~SharedWorkerRepositoryClientImpl() override {}
 
   void connect(SharedWorker*,
-               WebMessagePortChannelUniquePtr,
+               std::unique_ptr<WebMessagePortChannel>,
                const KURL&,
                const String& name) override;
   void documentDetached(Document*) override;
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
index 78a1b1af..fdc3901 100644
--- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
@@ -264,17 +264,18 @@
   return m_loadingContext;
 }
 
-void WebSharedWorkerImpl::connect(WebMessagePortChannel* webChannel) {
+void WebSharedWorkerImpl::connect(
+    std::unique_ptr<WebMessagePortChannel> webChannel) {
   DCHECK(isMainThread());
   workerThread()->postTask(
       BLINK_FROM_HERE,
       crossThreadBind(&WebSharedWorkerImpl::connectTaskOnWorkerThread,
                       WTF::crossThreadUnretained(this),
-                      WTF::passed(WebMessagePortChannelUniquePtr(webChannel))));
+                      WTF::passed(std::move(webChannel))));
 }
 
 void WebSharedWorkerImpl::connectTaskOnWorkerThread(
-    WebMessagePortChannelUniquePtr channel) {
+    std::unique_ptr<WebMessagePortChannel> channel) {
   // Wrap the passed-in channel in a MessagePort, and send it off via a connect
   // event.
   DCHECK(m_workerThread->isCurrentThread());
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
index 9e1134c3..334c42f 100644
--- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
+++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
@@ -90,7 +90,7 @@
                           const WebString& contentSecurityPolicy,
                           WebContentSecurityPolicyType,
                           WebAddressSpace) override;
-  void connect(WebMessagePortChannel*) override;
+  void connect(std::unique_ptr<WebMessagePortChannel>) override;
   void terminateWorkerContext() override;
 
   void pauseWorkerContextOnStart() override;
@@ -125,7 +125,7 @@
   void didReceiveScriptLoaderResponse();
   void onScriptLoaderFinished();
 
-  void connectTaskOnWorkerThread(WebMessagePortChannelUniquePtr);
+  void connectTaskOnWorkerThread(std::unique_ptr<WebMessagePortChannel>);
 
   // WorkerLoaderProxyProvider
   // postTaskToLoader() must be called from a worker thread.
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h
index 3fdfffe5..590bb87 100644
--- a/third_party/WebKit/public/platform/Platform.h
+++ b/third_party/WebKit/public/platform/Platform.h
@@ -46,6 +46,7 @@
 #include "WebGamepads.h"
 #include "WebGestureDevice.h"
 #include "WebLocalizedString.h"
+#include "WebMessagePortChannel.h"
 #include "WebPlatformEventType.h"
 #include "WebSize.h"
 #include "WebSpeechSynthesizer.h"
@@ -100,7 +101,6 @@
 class WebMediaStreamCenter;
 class WebMediaStreamCenterClient;
 class WebMediaStreamTrack;
-class WebMessagePortChannel;
 class WebNotificationManager;
 class WebPluginListBuilder;
 class WebPrescientNetworking;
@@ -317,10 +317,11 @@
   // Creates a Message Port Channel pair. This can be called on any thread.
   // The returned objects should only be used on the thread they were created
   // on.
-  virtual void createMessageChannel(WebMessagePortChannel** channel1,
-                                    WebMessagePortChannel** channel2) {
-    *channel1 = 0;
-    *channel2 = 0;
+  virtual void createMessageChannel(
+      std::unique_ptr<WebMessagePortChannel>* channel1,
+      std::unique_ptr<WebMessagePortChannel>* channel2) {
+    *channel1 = nullptr;
+    *channel2 = nullptr;
   }
 
   // Network -------------------------------------------------------------
diff --git a/third_party/WebKit/public/platform/WebContentSecurityPolicyStruct.h b/third_party/WebKit/public/platform/WebContentSecurityPolicyStruct.h
index e91858e..7f04023 100644
--- a/third_party/WebKit/public/platform/WebContentSecurityPolicyStruct.h
+++ b/third_party/WebKit/public/platform/WebContentSecurityPolicyStruct.h
@@ -63,7 +63,7 @@
   WebContentSecurityPolicySourceList sourceList;
 };
 
-struct WebContentSecurityPolicyPolicy {
+struct WebContentSecurityPolicy {
   WebContentSecurityPolicyType disposition;
   WebContentSecurityPolicySource source;
   WebVector<WebContentSecurityPolicyDirective> directives;
diff --git a/third_party/WebKit/public/platform/WebMessagePortChannel.h b/third_party/WebKit/public/platform/WebMessagePortChannel.h
index 8571553..b2e1dcb 100644
--- a/third_party/WebKit/public/platform/WebMessagePortChannel.h
+++ b/third_party/WebKit/public/platform/WebMessagePortChannel.h
@@ -38,11 +38,11 @@
 namespace blink {
 
 class WebMessagePortChannelClient;
+class WebMessagePortChannel;
 class WebString;
 
-using WebMessagePortChannelUniquePtr =
-    std::unique_ptr<class WebMessagePortChannel>;
-using WebMessagePortChannelArray = WebVector<WebMessagePortChannelUniquePtr>;
+using WebMessagePortChannelArray =
+    WebVector<std::unique_ptr<WebMessagePortChannel>>;
 
 // Provides an interface to a Message Port Channel implementation.
 class WebMessagePortChannel {
diff --git a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRequest.h b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRequest.h
index 3c1d0d7..e685b9b9 100644
--- a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRequest.h
+++ b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRequest.h
@@ -13,11 +13,11 @@
 #include "public/platform/WebURLRequest.h"
 
 #if INSIDE_BLINK
+#include <utility>
 #include "platform/network/HTTPHeaderMap.h"
 #include "platform/weborigin/Referrer.h"
 #include "wtf/Forward.h"
 #include "wtf/text/StringHash.h"
-#include <utility>
 #endif
 
 namespace blink {
@@ -43,10 +43,10 @@
   void assign(const WebServiceWorkerRequest&);
 
   void setURL(const WebURL&);
-  WebURL url() const;
+  const WebURL& url() const;
 
   void setMethod(const WebString&);
-  WebString method() const;
+  const WebString& method() const;
 
   void setHeader(const WebString& key, const WebString& value);
 
@@ -81,7 +81,7 @@
   WebURLRequest::FrameType frameType() const;
 
   void setClientId(const WebString&);
-  WebString clientId() const;
+  const WebString& clientId() const;
 
   void setIsReload(bool);
   bool isReload() const;
diff --git a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h
index 2acdcfb..2b1a76f85 100644
--- a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h
+++ b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h
@@ -51,7 +51,7 @@
   unsigned short status() const;
 
   void setStatusText(const WebString&);
-  WebString statusText() const;
+  const WebString& statusText() const;
 
   void setResponseType(WebServiceWorkerResponseType);
   WebServiceWorkerResponseType responseType() const;
@@ -71,7 +71,7 @@
   uint64_t blobSize() const;
 
   void setStreamURL(const WebURL&);
-  WebURL streamURL() const;
+  const WebURL& streamURL() const;
 
   // Provides a more detailed error when status() is zero.
   void setError(WebServiceWorkerResponseError);
@@ -81,10 +81,10 @@
   int64_t responseTime() const;
 
   void setCacheStorageCacheName(const WebString&);
-  WebString cacheStorageCacheName() const;
+  const WebString& cacheStorageCacheName() const;
 
   void setCorsExposedHeaderNames(const WebVector<WebString>&);
-  WebVector<WebString> corsExposedHeaderNames() const;
+  const WebVector<WebString>& corsExposedHeaderNames() const;
 
 #if INSIDE_BLINK
   const HTTPHeaderMap& headers() const;
diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h
index 9ea3567f6..4895d77 100644
--- a/third_party/WebKit/public/web/WebFrameClient.h
+++ b/third_party/WebKit/public/web/WebFrameClient.h
@@ -239,7 +239,7 @@
       const WebString& headerValue,
       WebContentSecurityPolicyType type,
       WebContentSecurityPolicySource source,
-      const std::vector<WebContentSecurityPolicyPolicy>& policies) {}
+      const std::vector<WebContentSecurityPolicy>& policies) {}
 
   // Some frame owner properties have changed for a child frame of this frame.
   // Frame owner properties currently include: scrolling, marginwidth and
diff --git a/third_party/WebKit/public/web/WebSharedWorker.h b/third_party/WebKit/public/web/WebSharedWorker.h
index b25b6933..7856032 100644
--- a/third_party/WebKit/public/web/WebSharedWorker.h
+++ b/third_party/WebKit/public/web/WebSharedWorker.h
@@ -57,7 +57,7 @@
                                   WebAddressSpace) = 0;
 
   // Sends a connect event to the SharedWorker context.
-  virtual void connect(WebMessagePortChannel*) = 0;
+  virtual void connect(std::unique_ptr<WebMessagePortChannel>) = 0;
 
   // Invoked to shutdown the worker when there are no more associated documents.
   // This eventually deletes this instance.
diff --git a/third_party/WebKit/public/web/WebSharedWorkerRepositoryClient.h b/third_party/WebKit/public/web/WebSharedWorkerRepositoryClient.h
index db36308..9c9d2a0 100644
--- a/third_party/WebKit/public/web/WebSharedWorkerRepositoryClient.h
+++ b/third_party/WebKit/public/web/WebSharedWorkerRepositoryClient.h
@@ -58,7 +58,7 @@
                        WebContentSecurityPolicyType,
                        WebAddressSpace,
                        WebSharedWorkerCreationContextType,
-                       WebMessagePortChannel*,
+                       std::unique_ptr<WebMessagePortChannel>,
                        std::unique_ptr<blink::WebSharedWorkerConnectListener>) {
   }
 
diff --git a/ui/file_manager/externs/compiled_resources2.gyp b/ui/file_manager/externs/compiled_resources2.gyp
index 77d9dcf..a205351 100644
--- a/ui/file_manager/externs/compiled_resources2.gyp
+++ b/ui/file_manager/externs/compiled_resources2.gyp
@@ -52,6 +52,10 @@
       'includes': ['../../../third_party/closure_compiler/include_js.gypi'],
     },
     {
+      'target_name': 'drag_target',
+      'includes': ['../../../third_party/closure_compiler/include_js.gypi'],
+    },
+    {
       'target_name': 'entries_changed_event',
       'includes': ['../../../third_party/closure_compiler/include_js.gypi'],
     },
diff --git a/ui/file_manager/externs/drag_target.js b/ui/file_manager/externs/drag_target.js
new file mode 100644
index 0000000..bcc4d8b
--- /dev/null
+++ b/ui/file_manager/externs/drag_target.js
@@ -0,0 +1,20 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @interface
+ */
+function DragTarget(){};
+
+/**
+ * This definition is required to satisfy
+ * ui/file_manager/file_manager/foreground/js/ui/drag_selector.js.
+ *
+ * @param {number} x
+ * @param {number} y
+ * @param {number=} opt_width
+ * @param {number=} opt_height
+ * @return {Array<number>}
+ */
+DragTarget.prototype.getHitElements = function(x, y, opt_width, opt_height) {};
diff --git a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
index 37260ea..017f7e0e 100644
--- a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
+++ b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
@@ -180,6 +180,7 @@
           '../../../externs/connection.js',
           '../../../externs/css_rule.js',
           '../../../externs/directory_change_event.js',
+          '../../../externs/drag_target.js',
           '../../../externs/entry_location.js',
           '../../../externs/es6_workaround.js',
           '../../../externs/file_browser_background.js',
diff --git a/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp b/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp
index 4d28863..7485c99 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp
+++ b/ui/file_manager/file_manager/foreground/js/ui/compiled_resources2.gyp
@@ -35,10 +35,15 @@
 #      'target_name': 'directory_tree',
 #      'includes': ['../../../../compile_js2.gypi'],
 #    },
-#    {
-#      'target_name': 'drag_selector',
-#      'includes': ['../../../../compile_js2.gypi'],
-#    },
+    {
+      'target_name': 'drag_selector',
+      'dependencies': [
+        '../../../../externs/compiled_resources2.gyp:drag_target',
+        '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:ui',
+        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:list',
+      ],
+      'includes': ['../../../../compile_js2.gypi'],
+    },
     {
       'target_name': 'empty_folder',
       'dependencies': [
@@ -57,10 +62,14 @@
 #      'target_name': 'file_grid',
 #      'includes': ['../../../../compile_js2.gypi'],
 #    },
-#    {
-#      'target_name': 'file_list_selection_model',
-#      'includes': ['../../../../compile_js2.gypi'],
-#    },
+    {
+      'target_name': 'file_list_selection_model',
+      'dependencies': [
+        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:list_single_selection_model',
+        '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:list_selection_model',
+      ],
+      'includes': ['../../../../compile_js2.gypi'],
+    },
     {
       'target_name': 'file_manager_dialog_base',
       'dependencies': [
@@ -75,10 +84,14 @@
 #      'target_name': 'file_manager_ui',
 #      'includes': ['../../../../compile_js2.gypi'],
 #    },
-#    {
-#      'target_name': 'file_metadata_formatter',
-#      'includes': ['../../../../compile_js2.gypi'],
-#    },
+    {
+      'target_name': 'file_metadata_formatter',
+      'dependencies': [
+        '../../../common/js/compiled_resources2.gyp:util',
+        '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:event_target',
+      ],
+      'includes': ['../../../../compile_js2.gypi'],
+    },
 #    {
 #      'target_name': 'file_table',
 #      'includes': ['../../../../compile_js2.gypi'],
diff --git a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js
index 5ac6985e..dbd9f73 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js
@@ -149,12 +149,12 @@
   borderBounds.height = borderBounds.bottom - borderBounds.top;
 
   // Collect items within the selection rect.
-  var currentSelection = this.target_.getHitElements(
-      borderBounds.left,
-      borderBounds.top,
-      borderBounds.width,
-      borderBounds.height);
-  var pointedElements = this.target_.getHitElements(pos.x, pos.y);
+  var currentSelection = (/** @type {DragTarget} */ (this.target_))
+                             .getHitElements(
+                                 borderBounds.left, borderBounds.top,
+                                 borderBounds.width, borderBounds.height);
+  var pointedElements =
+      (/** @type {DragTarget} */ (this.target_)).getHitElements(pos.x, pos.y);
   var leadIndex = pointedElements.length ? pointedElements[0] : -1;
 
   // Diff the selection between currentSelection and this.lastSelection_.
diff --git a/ui/webui/resources/js/cr/ui/compiled_resources2.gyp b/ui/webui/resources/js/cr/ui/compiled_resources2.gyp
index c5fa11de..6682f542 100644
--- a/ui/webui/resources/js/cr/ui/compiled_resources2.gyp
+++ b/ui/webui/resources/js/cr/ui/compiled_resources2.gyp
@@ -73,6 +73,31 @@
       'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
+      'target_name': 'list',
+      'dependencies': [
+        'array_data_model',
+        'list_item',
+        'list_selection_controller',
+        'list_selection_model',
+      ],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+    {
+      'target_name': 'list_item',
+      'dependencies': [
+        '../../compiled_resources2.gyp:cr',
+      ],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+    {
+      'target_name': 'list_selection_controller',
+      'dependencies': [
+        '../../compiled_resources2.gyp:cr',
+        'list_selection_model',
+      ],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+    {
       'target_name': 'list_selection_model',
       'dependencies': [
         '../../compiled_resources2.gyp:cr',
@@ -81,6 +106,14 @@
       'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
+      'target_name': 'list_single_selection_model',
+      'dependencies': [
+        '../../compiled_resources2.gyp:cr',
+        '../compiled_resources2.gyp:event_target',
+      ],
+      'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+    {
       'target_name': 'menu_button',
       'dependencies': [
         '../../compiled_resources2.gyp:assert',