diff --git a/DEPS b/DEPS
index 33a33bc..296d6a7 100644
--- a/DEPS
+++ b/DEPS
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'fe8a3c8a5cdb3f8ccb9edca2f3e7582fb2937c5b',
+  'catapult_revision': '4bd198f6a85c700acbbd23c0b666c846636526d2',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java
index 7490842..a91dd2f1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java
@@ -126,11 +126,6 @@
         mNativeDataReductionProxySettings = nativeInit();
     }
 
-    /** Returns true if the SPDY proxy is allowed to be used. */
-    public boolean isDataReductionProxyAllowed() {
-        return nativeIsDataReductionProxyAllowed(mNativeDataReductionProxySettings);
-    }
-
     /** Returns true if the SPDY proxy promo is allowed to be shown. */
     public boolean isDataReductionProxyPromoAllowed() {
         return nativeIsDataReductionProxyPromoAllowed(mNativeDataReductionProxySettings);
@@ -302,8 +297,6 @@
     }
 
     private native long nativeInit();
-    private native boolean nativeIsDataReductionProxyAllowed(
-            long nativeDataReductionProxySettingsAndroid);
     private native boolean nativeIsDataReductionProxyPromoAllowed(
             long nativeDataReductionProxySettingsAndroid);
     private native boolean nativeIsDataReductionProxyEnabled(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java
index 1c0c709..e1520073 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java
@@ -5,7 +5,6 @@
 package org.chromium.chrome.browser.omnibox.geo;
 
 import android.Manifest;
-import android.content.Context;
 import android.content.pm.PackageManager;
 import android.location.Location;
 import android.location.LocationManager;
@@ -13,6 +12,7 @@
 import android.os.Build;
 import android.os.Process;
 import android.os.SystemClock;
+import android.provider.Settings;
 import android.support.annotation.IntDef;
 import android.util.Base64;
 
@@ -31,7 +31,6 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.TimeUnit;
 
@@ -403,21 +402,40 @@
     /** Returns the location source. */
     @LocationSource
     private static int getLocationSource() {
-        LocationManager locationManager = (LocationManager) ContextUtils.getApplicationContext()
-                .getSystemService(Context.LOCATION_SERVICE);
-        List<String> providers = locationManager.getProviders(true);
-        boolean hasNetworkProvider = false;
-        boolean hasGpsProvider = false;
-        for (String provider : providers) {
-            if (LocationManager.NETWORK_PROVIDER.equals(provider)) {
-                hasNetworkProvider = true;
-            } else if (LocationManager.GPS_PROVIDER.equals(provider)) {
-                hasGpsProvider = true;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            int locationMode;
+            try {
+                locationMode = Settings.Secure.getInt(
+                        ContextUtils.getApplicationContext().getContentResolver(),
+                        Settings.Secure.LOCATION_MODE);
+            } catch (Settings.SettingNotFoundException e) {
+                Log.e(TAG, "Error getting the LOCATION_MODE");
+                return LOCATION_SOURCE_MASTER_OFF;
+            }
+            if (locationMode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) {
+                return LOCATION_SOURCE_HIGH_ACCURACY;
+            } else if (locationMode == Settings.Secure.LOCATION_MODE_SENSORS_ONLY) {
+                return LOCATION_SOURCE_GPS_ONLY;
+            } else if (locationMode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) {
+                return LOCATION_SOURCE_BATTERY_SAVING;
+            } else {
+                return LOCATION_SOURCE_MASTER_OFF;
+            }
+        } else {
+            String locationProviders = Settings.Secure.getString(
+                    ContextUtils.getApplicationContext().getContentResolver(),
+                    Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
+            if (locationProviders.contains(LocationManager.GPS_PROVIDER)
+                    && locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
+                return LOCATION_SOURCE_HIGH_ACCURACY;
+            } else if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
+                return LOCATION_SOURCE_GPS_ONLY;
+            } else if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
+                return LOCATION_SOURCE_BATTERY_SAVING;
+            } else {
+                return LOCATION_SOURCE_MASTER_OFF;
             }
         }
-        return hasNetworkProvider
-                ? (hasGpsProvider ? LOCATION_SOURCE_HIGH_ACCURACY : LOCATION_SOURCE_BATTERY_SAVING)
-                : (hasGpsProvider ? LOCATION_SOURCE_GPS_ONLY : LOCATION_SOURCE_MASTER_OFF);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java
index 1b6bfc3..a37d109 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java
@@ -143,13 +143,8 @@
 
         ChromeBasePreference dataReduction =
                 (ChromeBasePreference) findPreference(PREF_DATA_REDUCTION);
-        if (DataReductionProxySettings.getInstance().isDataReductionProxyAllowed()) {
-            dataReduction.setSummary(
-                    DataReductionPreferences.generateSummary(getResources()));
-            dataReduction.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
-        } else {
-            getPreferenceScreen().removePreference(dataReduction);
-        }
+        dataReduction.setSummary(DataReductionPreferences.generateSummary(getResources()));
+        dataReduction.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
 
         if (!SigninManager.get(getActivity()).isSigninSupported()) {
             getPreferenceScreen().removePreference(findPreference(PREF_SIGN_IN));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
index 5c20d1f..daf4d44 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -35,6 +35,7 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.webapps.WebappDataStorage;
 import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
+import org.chromium.chrome.test.util.InfoBarUtil;
 import org.chromium.chrome.test.util.browser.TabLoadObserver;
 import org.chromium.chrome.test.util.browser.TabTitleObserver;
 import org.chromium.chrome.test.util.browser.WebappTestPage;
@@ -220,15 +221,6 @@
         });
     }
 
-    private void waitUntilNoInfoBarsExist() {
-        CriteriaHelper.pollUiThread(new Criteria() {
-            @Override
-            public boolean isSatisfied() {
-                return getInfoBars().isEmpty();
-            }
-        });
-    }
-
     private void waitUntilAppDetailsRetrieved(final int numExpected) {
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
@@ -260,7 +252,7 @@
         // Visit a site that requests a banner.
         resetEngagementForUrl(url, 0);
         new TabLoadObserver(getActivity().getActivityTab()).fullyLoadUrl(url, PageTransition.TYPED);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         // Update engagement, then revisit the page to get the banner to appear.
         resetEngagementForUrl(url, 10);
@@ -328,7 +320,7 @@
                 return !manager.isActiveForTesting();
             }
         });
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         // Add the animation listener in.
         InfoBarContainer container = getActivity().getActivityTab().getInfoBarContainer();
@@ -382,7 +374,7 @@
         resetEngagementForUrl(mNativeAppUrl, 0);
         new TabLoadObserver(getActivity().getActivityTab())
                 .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         // Update engagement, then revisit the page.
         resetEngagementForUrl(mNativeAppUrl, 10);
@@ -396,20 +388,20 @@
         new TabLoadObserver(getActivity().getActivityTab())
                 .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
         waitUntilAppDetailsRetrieved(2);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         // Wait a week until revisiting the page.
         AppBannerManager.setTimeDeltaForTesting(7);
         new TabLoadObserver(getActivity().getActivityTab())
                 .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
         waitUntilAppDetailsRetrieved(3);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         AppBannerManager.setTimeDeltaForTesting(8);
         new TabLoadObserver(getActivity().getActivityTab())
                 .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
         waitUntilAppDetailsRetrieved(4);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         // Wait two weeks until revisiting the page, which should pop up the banner.
         AppBannerManager.setTimeDeltaForTesting(15);
@@ -430,7 +422,7 @@
         // This hides the banner for two weeks.
         new TabLoadObserver(getActivity().getActivityTab())
                 .fullyLoadUrl(mWebAppUrl, PageTransition.TYPED);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         // Wait a week until revisiting the page. This should allow the banner.
         AppBannerManager.setTimeDeltaForTesting(7);
@@ -446,7 +438,7 @@
         resetEngagementForUrl(mNativeAppUrl, 0);
         new TabLoadObserver(getActivity().getActivityTab())
                 .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         // Update engagement, then revisit the page.
         resetEngagementForUrl(mNativeAppUrl, 10);
@@ -468,20 +460,20 @@
         ArrayList<InfoBar> infobars = container.getInfoBarsForTesting();
         View close = infobars.get(0).getView().findViewById(R.id.infobar_close_button);
         TouchCommon.singleClickView(close);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         // Waiting two months shouldn't be long enough.
         AppBannerManager.setTimeDeltaForTesting(61);
         new TabLoadObserver(getActivity().getActivityTab())
                 .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
         waitUntilAppDetailsRetrieved(2);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         AppBannerManager.setTimeDeltaForTesting(62);
         new TabLoadObserver(getActivity().getActivityTab())
                 .fullyLoadUrl(mNativeAppUrl, PageTransition.TYPED);
         waitUntilAppDetailsRetrieved(3);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         // Waiting three months should allow banners to reappear.
         AppBannerManager.setTimeDeltaForTesting(91);
@@ -515,7 +507,7 @@
         ArrayList<InfoBar> infobars = container.getInfoBarsForTesting();
         View close = infobars.get(0).getView().findViewById(R.id.infobar_close_button);
         TouchCommon.singleClickView(close);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         // Waiting seven days should be long enough.
         AppBannerManager.setTimeDeltaForTesting(7);
@@ -558,7 +550,7 @@
         AppBannerManager.setTimeDeltaForTesting(100);
         new TabLoadObserver(getActivity().getActivityTab())
                 .fullyLoadUrl(mWebAppUrl, PageTransition.TYPED);
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
     }
 
     @SmallTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/SystemDownloadNotifierTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/SystemDownloadNotifierTest.java
index 4a568b11..f2a27bb 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/SystemDownloadNotifierTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/SystemDownloadNotifierTest.java
@@ -81,7 +81,6 @@
         DownloadInfo info = new DownloadInfo.Builder()
                 .setDownloadGuid(UUID.randomUUID().toString()).build();
         mDownloadNotifier.notifyDownloadProgress(info, 1L, true);
-        assertFalse(mDownloadNotifier.mStarted);
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
@@ -103,7 +102,6 @@
         DownloadInfo info = new DownloadInfo.Builder()
                 .setDownloadGuid(UUID.randomUUID().toString()).build();
         mDownloadNotifier.notifyDownloadProgress(info, 1L, true);
-        assertFalse(mDownloadNotifier.mStarted);
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
             public boolean isSatisfied() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java
index 7e5ea3d..2fd48a1 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java
@@ -57,15 +57,6 @@
     private EmbeddedTestServer mTestServer;
     private InfoBarTestAnimationListener mListener;
 
-    private void waitUntilNoInfoBarsExist() {
-        CriteriaHelper.pollUiThread(new Criteria() {
-            @Override
-            public boolean isSatisfied() {
-                return getInfoBars().isEmpty();
-            }
-        });
-    }
-
     private void waitUntilDataReductionPromoInfoBarAppears() {
         CriteriaHelper.pollUiThread(new Criteria() {
             @Override
@@ -186,14 +177,7 @@
                         getActivity().getActivityTab().goBack();
                     }
                 });
-        CriteriaHelper.pollInstrumentationThread(
-                new Criteria() {
-                    @Override
-                    public boolean isSatisfied() {
-                        return getInfoBars().isEmpty();
-                    }
-                },
-                MAX_TIMEOUT, CHECK_INTERVAL);
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
         mListener.removeInfoBarAnimationFinished("InfoBar not removed.");
     }
 
@@ -239,7 +223,7 @@
         });
 
         // The renderer should have been killed and the infobar removed.
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -300,7 +284,7 @@
         });
 
         // The renderer should have been killed and the infobar removed.
-        waitUntilNoInfoBarsExist();
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java
index a8d2502..e8502dd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBarTest.java
@@ -8,7 +8,6 @@
 
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.FlakyTest;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.SearchGeolocationDisclosureTabHelper;
 import org.chromium.chrome.test.ChromeActivityTestCaseBase;
@@ -50,7 +49,6 @@
         super.tearDown();
     }
 
-    @FlakyTest(message = "https://crbug.com/678210")
     @SmallTest
     @Feature({"Browser", "Main"})
     @CommandLineFlags.Add(ENABLE_NEW_DISCLOSURE_FEATURE)
@@ -74,6 +72,9 @@
 
         // Infobar should not appear again on the same day.
         loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        // There can be a delay from infobars being removed in the native InfobarManager and them
+        // being removed in the Java container, so wait until the infobar has really gone.
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
         assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
 
         // Infobar should appear again the next day.
@@ -86,6 +87,7 @@
 
         // Infobar should not appear again on the same day.
         loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
         assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
 
         // Infobar should appear again the next day.
@@ -98,6 +100,7 @@
 
         // Infobar should not appear again on the same day.
         loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
         assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
 
         // Infobar has appeared three times now, it should not appear again.
@@ -126,6 +129,7 @@
 
         // Infobar should not appear again on the same day.
         loadUrl(mTestServer.getURL(SEARCH_PAGE));
+        InfoBarUtil.waitUntilNoInfoBarsExist(getInfoBars());
         assertEquals("Wrong infobar count after search", 0, getInfoBars().size());
 
         // Infobar should not appear the next day either, as it has been dismissed.
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc
index 7f6c6d73..9261650 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc
@@ -58,8 +58,7 @@
   DCHECK(net_log);
   DCHECK(prefs);
 
-  int flags = DataReductionProxyParams::kAllowed |
-              DataReductionProxyParams::kFallbackAllowed;
+  int flags = 0;
   if (data_reduction_proxy::params::IsIncludedInPromoFieldTrial())
     flags |= DataReductionProxyParams::kPromoAllowed;
   if (data_reduction_proxy::params::IsIncludedInHoldbackFieldTrial())
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
index 49e70c9..37d0050 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
@@ -35,12 +35,6 @@
 DataReductionProxySettingsAndroid::~DataReductionProxySettingsAndroid() {
 }
 
-jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyAllowed(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& obj) {
-  return Settings()->Allowed();
-}
-
 jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyPromoAllowed(
     JNIEnv* env,
     const JavaParamRef<jobject>& obj) {
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h
index 6348bb6..2c0258c8 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h
@@ -35,9 +35,6 @@
   void InitDataReductionProxySettings(Profile* profile);
 
   // JNI wrapper interfaces to the indentically-named superclass methods.
-  jboolean IsDataReductionProxyAllowed(
-      JNIEnv* env,
-      const base::android::JavaParamRef<jobject>& obj);
   jboolean IsDataReductionProxyPromoAllowed(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& obj);
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc
index 3495ebe4..c4928f0c 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc
@@ -62,15 +62,9 @@
 template <class C>
 void data_reduction_proxy::DataReductionProxySettingsTestBase::ResetSettings(
     std::unique_ptr<base::Clock> clock,
-    bool allowed,
-    bool fallback_allowed,
     bool promo_allowed,
     bool holdback) {
   int flags = 0;
-  if (allowed)
-    flags |= DataReductionProxyParams::kAllowed;
-  if (fallback_allowed)
-    flags |= DataReductionProxyParams::kFallbackAllowed;
   if (promo_allowed)
     flags |= DataReductionProxyParams::kPromoAllowed;
   if (holdback)
@@ -94,8 +88,6 @@
 template void
 data_reduction_proxy::DataReductionProxySettingsTestBase::ResetSettings<
     DataReductionProxyChromeSettings>(std::unique_ptr<base::Clock> clock,
-                                      bool allowed,
-                                      bool fallback_allowed,
                                       bool promo_allowed,
                                       bool holdback);
 
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.cc b/chrome/browser/predictors/resource_prefetch_predictor.cc
index f333d10..3c5da28 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor.cc
@@ -13,6 +13,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/sparse_histogram.h"
+#include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
@@ -56,6 +57,9 @@
                                 "application/font-sfnt",
                                 "application/font-ttf"};
 
+const size_t kNumSampleHosts = 50;
+const size_t kReportReadinessThreshold = 50;
+
 // For reporting events of interest that are not tied to any navigation.
 enum ReportingEvent {
   REPORTING_EVENT_ALL_HISTORY_CLEARED = 0,
@@ -609,6 +613,14 @@
           base::Bind(&ResourcePrefetchPredictor::OnVisitCountLookup,
                      AsWeakPtr()))),
       &history_lookup_consumer_);
+
+  // Report readiness metric with 20% probability.
+  if (base::RandInt(1, 5) == 5) {
+    history_service->TopHosts(
+        kNumSampleHosts,
+        base::Bind(&ResourcePrefetchPredictor::ReportDatabaseReadiness,
+                   AsWeakPtr()));
+  }
 }
 
 bool ResourcePrefetchPredictor::GetPrefetchData(const GURL& main_frame_url,
@@ -651,15 +663,8 @@
 
   size_t initial_size = urls->size();
   for (const ResourceData& resource : it->second.resources()) {
-    float confidence =
-        static_cast<float>(resource.number_of_hits()) /
-        (resource.number_of_hits() + resource.number_of_misses());
-    if (confidence < config_.min_resource_confidence_to_trigger_prefetch ||
-        resource.number_of_hits() <
-            config_.min_resource_hits_to_trigger_prefetch)
-      continue;
-
-    urls->push_back(GURL(resource.resource_url()));
+    if (IsResourcePrefetchable(resource))
+      urls->push_back(GURL(resource.resource_url()));
   }
 
   return urls->size() > initial_size;
@@ -1105,6 +1110,58 @@
   }
 }
 
+bool ResourcePrefetchPredictor::IsDataPrefetchable(
+    const std::string& main_frame_key,
+    const PrefetchDataMap& data_map) const {
+  PrefetchDataMap::const_iterator it = data_map.find(main_frame_key);
+  if (it == data_map.end())
+    return false;
+
+  return std::any_of(it->second.resources().begin(),
+                     it->second.resources().end(),
+                     [this](const ResourceData& resource) {
+                       return IsResourcePrefetchable(resource);
+                     });
+}
+
+bool ResourcePrefetchPredictor::IsResourcePrefetchable(
+    const ResourceData& resource) const {
+  float confidence = static_cast<float>(resource.number_of_hits()) /
+                     (resource.number_of_hits() + resource.number_of_misses());
+  return confidence >= config_.min_resource_confidence_to_trigger_prefetch &&
+         resource.number_of_hits() >=
+             config_.min_resource_hits_to_trigger_prefetch;
+}
+
+void ResourcePrefetchPredictor::ReportDatabaseReadiness(
+    const history::TopHostsList& top_hosts) const {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (top_hosts.size() == 0)
+    return;
+
+  size_t count_in_cache = 0;
+  size_t total_visits = 0;
+  for (const std::pair<std::string, int>& top_host : top_hosts) {
+    const std::string& host = top_host.first;
+    total_visits += top_host.second;
+
+    // Hostnames in TopHostsLists are stripped of their 'www.' prefix. We
+    // assume that www.foo.com entry from |host_table_cache_| is also suitable
+    // for foo.com.
+    if (IsDataPrefetchable(host, *host_table_cache_) ||
+        (!base::StartsWith(host, "www.", base::CompareCase::SENSITIVE) &&
+         IsDataPrefetchable("www." + host, *host_table_cache_))) {
+      ++count_in_cache;
+    }
+  }
+
+  // Filter users that don't have the rich browsing history.
+  if (total_visits > kReportReadinessThreshold) {
+    UMA_HISTOGRAM_PERCENTAGE("ResourcePrefetchPredictor.DatabaseReadiness",
+                             100 * count_in_cache / top_hosts.size());
+  }
+}
+
 void ResourcePrefetchPredictor::OnURLsDeleted(
     history::HistoryService* history_service,
     bool all_history,
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.h b/chrome/browser/predictors/resource_prefetch_predictor.h
index ae2a57c..fcc1e39 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor.h
+++ b/chrome/browser/predictors/resource_prefetch_predictor.h
@@ -311,15 +311,18 @@
                      size_t max_redirect_map_size,
                      RedirectDataMap* redirect_map);
 
-  // Reports overall page load time.
-  void ReportPageLoadTimeStats(base::TimeDelta plt) const;
+  // Returns true iff the |data_map| contains PrefetchData that can be used
+  // for |main_frame_key| prefetching.
+  bool IsDataPrefetchable(const std::string& main_frame_key,
+                          const PrefetchDataMap& data_map) const;
 
-  // Reports page load time for prefetched and not prefetched pages.
-  void ReportPageLoadTimePrefetchStats(
-      base::TimeDelta plt,
-      bool prefetched,
-      base::Callback<void(int)> report_network_type_callback,
-      PrefetchKeyType key_type) const;
+  // Returns true iff |resource| has sufficient confidence level and required
+  // number of hits.
+  bool IsResourcePrefetchable(const ResourceData& resource) const;
+
+  // Reports database readiness metric defined as percentage of navigated hosts
+  // found in DB for last X entries in history.
+  void ReportDatabaseReadiness(const history::TopHostsList& top_hosts) const;
 
   // history::HistoryServiceObserver:
   void OnURLsDeleted(history::HistoryService* history_service,
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
index 0d57751..b4aaaee2 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
@@ -388,9 +388,6 @@
     drp_test_context_ =
         data_reduction_proxy::DataReductionProxyTestContext::Builder()
             .WithParamsFlags(
-                 data_reduction_proxy::DataReductionProxyParams::kAllowed |
-                 data_reduction_proxy::DataReductionProxyParams::
-                     kFallbackAllowed |
                  data_reduction_proxy::DataReductionProxyParams::kPromoAllowed)
             .WithMockConfig()
             .SkipSettingsInitialization()
diff --git a/chrome/browser/resources/md_bookmarks/app.html b/chrome/browser/resources/md_bookmarks/app.html
index b4f204b..4b49100 100644
--- a/chrome/browser/resources/md_bookmarks/app.html
+++ b/chrome/browser/resources/md_bookmarks/app.html
@@ -30,15 +30,16 @@
         flex: 1;
       }
     </style>
-    <bookmarks-toolbar></bookmarks-toolbar>
+    <bookmarks-toolbar search-term="[[searchTerm]]"></bookmarks-toolbar>
     <div id="main-container">
       <bookmarks-sidebar root-folders="[[rootNode.children]]">
       </bookmarks-sidebar>
-      <bookmarks-list selected-node="[[selectedNode]]"></bookmarks-list>
+      <bookmarks-list displayed-list="[[displayedList]]"></bookmarks-list>
     </div>
     <bookmarks-store selected-id="{{selectedId}}"
-        selected-node="{{selectedNode}}"
-        root-node="{{rootNode}}">
+        root-node="{{rootNode}}"
+        search-term="{{searchTerm}}"
+        displayed-list="{{displayedList}}">
     </bookmarks-store>
   </template>
   <script src="chrome://bookmarks/app.js"></script>
diff --git a/chrome/browser/resources/md_bookmarks/app.js b/chrome/browser/resources/md_bookmarks/app.js
index 9ffe45ef..89d6310 100644
--- a/chrome/browser/resources/md_bookmarks/app.js
+++ b/chrome/browser/resources/md_bookmarks/app.js
@@ -9,10 +9,12 @@
     selectedId: String,
 
     /** @type {BookmarkTreeNode} */
-    selectedNode: Object,
-
-    /** @type {BookmarkTreeNode} */
     rootNode: Object,
+
+    searchTerm: String,
+
+    /** @type {Array<BookmarkTreeNode>} */
+    displayedList: Array,
   },
 
   /** @override */
diff --git a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp
index 318e2f9d..9237fbd 100644
--- a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp
+++ b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp
@@ -55,6 +55,7 @@
       'target_name': 'toolbar',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp:cr_action_menu',
+        '<(DEPTH)/ui/webui/resources/cr_elements/cr_toolbar/compiled_resources2.gyp:cr_toolbar',
       ],
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
diff --git a/chrome/browser/resources/md_bookmarks/list.html b/chrome/browser/resources/md_bookmarks/list.html
index 8dd6be98..2cc1dc0 100644
--- a/chrome/browser/resources/md_bookmarks/list.html
+++ b/chrome/browser/resources/md_bookmarks/list.html
@@ -67,14 +67,13 @@
         </paper-button>
       </div>
     </dialog>
-    <div id="bookmarksCard">
-      <hidden$="[[isListEmpty_(selectedNode.children.length)]]">
-      <template is="dom-repeat" items="[[selectedNode.children]]" as="item">
+    <div id="bookmarksCard" hidden$="[[isListEmpty_(displayedList.length)]]">
+      <template is="dom-repeat" items="[[displayedList]]" as="item">
         <bookmarks-item item="[[item]]"></bookmarks-item>
       </template>
     </div>
     <div class="centered-message"
-        hidden$="[[!isListEmpty_(selectedNode.children.length)]]">
+        hidden$="[[!isListEmpty_(displayedList.length)]]">
       $i18n{emptyList}
     </div>
   </template>
diff --git a/chrome/browser/resources/md_bookmarks/list.js b/chrome/browser/resources/md_bookmarks/list.js
index f1c3b6b6..3c1ad92 100644
--- a/chrome/browser/resources/md_bookmarks/list.js
+++ b/chrome/browser/resources/md_bookmarks/list.js
@@ -7,10 +7,10 @@
 
   properties: {
     /** @type {BookmarkTreeNode} */
-    selectedNode: Object,
-
-    /** @type {BookmarkTreeNode} */
     menuItem_: Object,
+
+    /** @type {Array<BookmarkTreeNode>} */
+    displayedList: Array,
   },
 
   listeners: {
@@ -47,12 +47,12 @@
 
   /** @private */
   onDeleteTap_: function() {
-    if (this.menuItem_.children) {
-      chrome.bookmarks.removeTree(this.menuItem_.id, function() {
+    if (this.menuItem_.url) {
+      chrome.bookmarks.remove(this.menuItem_.id, function() {
         // TODO(jiaxi): Add toast later.
       }.bind(this));
     } else {
-      chrome.bookmarks.remove(this.menuItem_.id, function() {
+      chrome.bookmarks.removeTree(this.menuItem_.id, function() {
         // TODO(jiaxi): Add toast later.
       }.bind(this));
     }
@@ -82,6 +82,6 @@
 
   /** @private */
   isListEmpty_: function() {
-    return this.selectedNode.children.length == 0;
+    return this.displayedList.length == 0;
   }
 });
diff --git a/chrome/browser/resources/md_bookmarks/store.js b/chrome/browser/resources/md_bookmarks/store.js
index bdbcb2e..baddea2 100644
--- a/chrome/browser/resources/md_bookmarks/store.js
+++ b/chrome/browser/resources/md_bookmarks/store.js
@@ -12,15 +12,26 @@
       notify: true,
     },
 
+    /** @type {?string} */
     selectedId: {
       type: String,
-      observer: 'updateSelectedNode_',
+      observer: 'updateSelectedDisplay_',
       notify: true,
     },
 
-    /** @type {BookmarkTreeNode} */
-    selectedNode: {
-      type: Object,
+    searchTerm: {
+      type: String,
+      observer: 'updateSearchDisplay_',
+      notify: true,
+    },
+
+    /**
+     * This updates to either the result of a search or the contents of the
+     * selected folder.
+     * @type {Array<BookmarkTreeNode>}
+     */
+    displayedList: {
+      type: Array,
       notify: true,
       readOnly: true,
     },
@@ -36,6 +47,7 @@
     this.documentListeners_ = {
       'selected-folder-changed': this.onSelectedFolderChanged_.bind(this),
       'folder-open-changed': this.onFolderOpenChanged_.bind(this),
+      'search-term-changed': this.onSearchTermChanged_.bind(this),
     };
     for (var event in this.documentListeners_)
       document.addEventListener(event, this.documentListeners_[event]);
@@ -76,20 +88,49 @@
     this.fire('selected-folder-changed', this.rootNode.children[0].id);
   },
 
+  /** @private */
+  deselectFolders_: function() {
+    this.unlinkPaths('displayedList');
+    this.set(this.idToNodeMap_[this.selectedId].path + '.isSelected', false);
+    this.selectedId = null;
+  },
+
   /**
    * @param {BookmarkTreeNode} folder
    * @private
    * @return {boolean}
    */
   isAncestorOfSelected_: function(folder) {
-    return this.selectedNode.path.startsWith(folder.path);
+    if (!this.selectedId)
+      return false;
+
+    var selectedNode = this.idToNodeMap_[this.selectedId];
+    return selectedNode.path.startsWith(folder.path);
   },
 
   /** @private */
-  updateSelectedNode_: function() {
+  updateSearchDisplay_: function() {
+    if (this.searchTerm == '') {
+      this.fire('selected-folder-changed', this.rootNode.children[0].id);
+    } else {
+      chrome.bookmarks.search(this.searchTerm, function(results) {
+        if (this.selectedId)
+          this.deselectFolders_();
+
+        this._setDisplayedList(results);
+      }.bind(this));
+    }
+  },
+
+  /** @private */
+  updateSelectedDisplay_: function() {
+    // Don't change to the selected display if ID was cleared.
+    if (!this.selectedId)
+      return;
+
     var selectedNode = this.idToNodeMap_[this.selectedId];
-    this.linkPaths('selectedNode', selectedNode.path);
-    this._setSelectedNode(selectedNode);
+    this.linkPaths('displayedList', selectedNode.path + '.children');
+    this._setDisplayedList(selectedNode.children);
   },
 
   /**
@@ -129,6 +170,10 @@
     this.splice(parentNode.path + '.children', removeInfo.index, 1);
     this.removeDescendantsFromMap_(id);
     BookmarksStore.generatePaths(parentNode, removeInfo.index);
+
+    // Regenerate the search list if its displayed.
+    if (this.searchTerm)
+      this.updateSearchDisplay_();
   },
 
   /**
@@ -141,18 +186,32 @@
       this.set(this.idToNodeMap_[id].path + '.title', changeInfo.title);
     if (changeInfo.url)
       this.set(this.idToNodeMap_[id].path + '.url', changeInfo.url);
+
+    if (this.searchTerm)
+      this.updateSearchDisplay_();
   },
 
 ////////////////////////////////////////////////////////////////////////////////
 // bookmarks-store, bookmarks app event listeners:
 
   /**
+   * @param {Event} e
+   * @private
+   */
+  onSearchTermChanged_: function(e) {
+    this.searchTerm = /** @type {string} */ (e.detail);
+  },
+
+  /**
    * Selects the folder specified by the event and deselects the previously
    * selected folder.
    * @param {CustomEvent} e
    * @private
    */
   onSelectedFolderChanged_: function(e) {
+    if (this.searchTerm)
+      this.searchTerm = '';
+
     // Deselect the old folder if defined.
     if (this.selectedId)
       this.set(this.idToNodeMap_[this.selectedId].path + '.isSelected', false);
diff --git a/chrome/browser/resources/md_bookmarks/toolbar.html b/chrome/browser/resources/md_bookmarks/toolbar.html
index 14cd1648..75f566fb 100644
--- a/chrome/browser/resources/md_bookmarks/toolbar.html
+++ b/chrome/browser/resources/md_bookmarks/toolbar.html
@@ -45,7 +45,8 @@
     </dialog>
     <cr-toolbar page-name="$i18n{title}"
         clear-label="$i18n{clearSearch}"
-        search-prompt="$i18n{searchPrompt}">
+        search-prompt="$i18n{searchPrompt}"
+        on-search-changed="onSearchChanged_">
       <button is="paper-icon-button-light" class="more-actions more-vert-button"
           on-tap="onMenuButtonOpenTap_">
         <div></div>
diff --git a/chrome/browser/resources/md_bookmarks/toolbar.js b/chrome/browser/resources/md_bookmarks/toolbar.js
index b1d982c..bfce3d0d 100644
--- a/chrome/browser/resources/md_bookmarks/toolbar.js
+++ b/chrome/browser/resources/md_bookmarks/toolbar.js
@@ -5,6 +5,19 @@
 Polymer({
   is: 'bookmarks-toolbar',
 
+  properties: {
+    searchTerm: {
+      type: String,
+      observer: 'onSearchTermChanged_',
+    },
+  },
+
+  /** @return {CrToolbarSearchFieldElement} */
+  get searchField() {
+    return /** @type {CrToolbarElement} */ (this.$$('cr-toolbar'))
+        .getSearchField();
+  },
+
   /**
    * @param {Event} e
    * @private
@@ -43,5 +56,20 @@
   closeDropdownMenu_: function() {
     var menu = /** @type {!CrActionMenuElement} */ (this.$.dropdown);
     menu.close();
-  }
+  },
+
+  /**
+   * @param {Event} e
+   * @private
+   */
+  onSearchChanged_: function(e) {
+    var searchTerm = /** @type {string} */ (e.detail);
+    this.fire('search-term-changed', searchTerm);
+  },
+
+  /** @private */
+  onSearchTermChanged_: function() {
+    if (!this.searchTerm)
+      this.searchField.setValue('');
+  },
 });
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html
index e37bd57..f9fe8ce7 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -58,78 +58,94 @@
     </template>
     <settings-animated-pages id="pages" section="privacy">
       <neon-animatable route-path="default">
-        <div class="settings-box block first">
+        <div class="settings-box first">
           <p class="privacy-explanation">$i18nRaw{improveBrowsingExperience}</p>
-          <settings-toggle-button
+        </div>
+        <div class="settings-box">
+          <settings-toggle-button class="start"
               pref="{{prefs.alternate_error_pages.enabled}}"
               label="$i18n{linkDoctorPref}">
           </settings-toggle-button>
-          <settings-toggle-button
+        </div>
+        <div class="settings-box">
+          <settings-toggle-button class="start"
               pref="{{prefs.search.suggest_enabled}}"
               label="$i18n{searchSuggestPref}"
               hidden="[[!pageVisibility.searchPrediction]]">
           </settings-toggle-button>
-          <settings-toggle-button
+        </div>
+        <div class="settings-box">
+          <settings-toggle-button class="start"
               pref="{{prefs.net.network_prediction_options}}"
               label="$i18n{networkPredictionEnabled}"
               hidden="[[!pageVisibility.networkPrediction]]">
           </settings-toggle-button>
-          <div class="layout horizontal center settings-row-min-height">
-            <div class="flex">$i18n{safeBrowsingEnableExtendedReporting}</div>
-            <paper-toggle-button id="safeBrowsingExtendedReportingControl"
-                on-tap="onSafeBrowsingExtendedReportingControlTap_"
-                checked="[[safeBrowsingExtendedReportingEnabled_]]">
-            </paper-toggle-button>
-          </div>
-          <settings-toggle-button
+        </div>
+        <div class="settings-box">
+          <div class="start">$i18n{safeBrowsingEnableExtendedReporting}</div>
+          <paper-toggle-button id="safeBrowsingExtendedReportingControl"
+              on-tap="onSafeBrowsingExtendedReportingControlTap_"
+              checked="[[safeBrowsingExtendedReportingEnabled_]]">
+          </paper-toggle-button>
+        </div>
+        <div class="settings-box">
+          <settings-toggle-button class="start"
               pref="{{prefs.safebrowsing.enabled}}"
               label="$i18n{safeBrowsingEnableProtection}">
           </settings-toggle-button>
+        </div>
 <if expr="_google_chrome">
 <if expr="chromeos">
-          <settings-toggle-button
+        <div class="settings-box">
+          <settings-toggle-button class="start"
               pref="{{prefs.cros.metrics.reportingEnabled}}"
               label="$i18n{enableLogging}">
           </settings-toggle-button>
+        </div>
 </if><!-- chromeos -->
 <if expr="not chromeos">
-          <div class="layout horizontal center settings-row-min-height">
-            <div class="flex">$i18n{enableLogging}</div>
-            <template is="dom-if" if="[[showRestart_]]" restamp>
-              <paper-button on-tap="onRestartTap_" id="restart">
-                $i18n{restart}
-              </paper-button>
-            </template>
-            <template is="dom-if" if="[[metricsReporting_.managed]]" restamp>
-              <iron-icon id="indicator" tabindex=0 icon="cr:domain"></iron-icon>
-              <paper-tooltip for="indicator" position="top"
-                  fit-to-visible-bounds>
-                $i18n{controlledSettingPolicy}
-              </paper-tooltip>
-            </template>
-            <paper-toggle-button id="metricsReportingControl"
-                on-tap="onMetricsReportingControlTap_"
-                checked="[[metricsReporting_.enabled]]"
-                disabled="[[metricsReporting_.managed]]">
-            </paper-toggle-button>
-          </div>
+        <div class="settings-box">
+          <div class="start">$i18n{enableLogging}</div>
+          <template is="dom-if" if="[[showRestart_]]" restamp>
+            <paper-button on-tap="onRestartTap_" id="restart">
+              $i18n{restart}
+            </paper-button>
+          </template>
+          <template is="dom-if" if="[[metricsReporting_.managed]]" restamp>
+            <iron-icon id="indicator" tabindex=0 icon="cr:domain"></iron-icon>
+            <paper-tooltip for="indicator" position="top"
+                fit-to-visible-bounds>
+              $i18n{controlledSettingPolicy}
+            </paper-tooltip>
+          </template>
+          <paper-toggle-button id="metricsReportingControl"
+              on-tap="onMetricsReportingControlTap_"
+              checked="[[metricsReporting_.enabled]]"
+              disabled="[[metricsReporting_.managed]]">
+          </paper-toggle-button>
+        </div>
 </if><!-- not chromeos -->
 </if><!-- _google_chrome -->
-          <settings-toggle-button
+        <div class="settings-box">
+          <settings-toggle-button class="start"
               pref="{{prefs.enable_do_not_track}}"
               label="$i18n{doNotTrack}">
           </settings-toggle-button>
+        </div>
 <if expr="chromeos">
-          <settings-toggle-button
+        <div class="settings-box">
+          <settings-toggle-button class="start"
               pref="{{prefs.cros.device.attestation_for_content_protection_enabled}}"
               label="$i18n{enableContentProtectionAttestation}">
           </settings-toggle-button>
-          <settings-toggle-button
+        </div>
+        <div class="settings-box">
+          <settings-toggle-button class="start"
               pref="{{prefs.settings.internet.wake_on_wifi_darkconnect}}"
               label="$i18n{wakeOnWifi}">
           </settings-toggle-button>
-</if>
         </div>
+</if>
 <if expr="_google_chrome">
         <div class="settings-box two-line">
           <settings-toggle-button class="start"
@@ -143,7 +159,7 @@
         <div id="manageCertificates" class="settings-box two-line"
             actionable on-tap="onManageCertificatesTap_">
           <div class="start">
-            <div>$i18n{manageCertificates}</div>
+            $i18n{manageCertificates}
             <div class="secondary">$i18n{manageCertificatesDescription}</div>
           </div>
 <if expr="use_nss_certs">
@@ -158,7 +174,7 @@
             class="settings-box two-line" actionable
             on-tap="onSiteSettingsTap_">
           <div class="start">
-            <div>[[siteSettingsPageTitle_()]]</div>
+            [[siteSettingsPageTitle_()]]
             <div class="secondary">$i18n{siteSettingsDescription}</div>
           </div>
           <button class="subpage-arrow" is="paper-icon-button-light"></button>
diff --git a/chrome/browser/resources/settings/system_page/system_page.html b/chrome/browser/resources/settings/system_page/system_page.html
index db416e60..7018147 100644
--- a/chrome/browser/resources/settings/system_page/system_page.html
+++ b/chrome/browser/resources/settings/system_page/system_page.html
@@ -1,5 +1,4 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="/controls/controlled_button.html">
 <link rel="import" href="/controls/extension_controlled_indicator.html">
@@ -12,14 +11,16 @@
 <dom-module id="settings-system-page">
   <template>
     <style include="settings-shared"></style>
-    <div class="settings-box block first">
+    <div class="settings-box first">
 <if expr="not is_macosx">
-      <settings-toggle-button
+      <settings-toggle-button class="start"
           pref="{{prefs.background_mode.enabled}}"
           label="$i18n{backgroundAppsLabel}">
       </settings-toggle-button>
+    </div>
+    <div class="settings-box">
 </if>
-      <settings-toggle-button class="flex" id="hardwareAcceleration"
+      <settings-toggle-button class="start" id="hardwareAcceleration"
           pref="{{prefs.hardware_acceleration_mode.enabled}}"
           label="$i18n{hardwareAccelerationLabel}">
         <template is="dom-if" if="[[shouldShowRestart_(
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index b95cef8..a8261f1 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2115,7 +2115,10 @@
     ]
   }
   if (is_win || is_linux) {
-    deps += [ "//components/payments:payment_request_impl" ]
+    deps += [
+      "//components/payments:payment_request_impl",
+      "//components/payments:payment_validation",
+    ]
   }
   if (enable_print_preview) {
     sources += [
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.cc b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
index cd87f46..38e576e 100644
--- a/chrome/browser/ui/views/payments/order_summary_view_controller.cc
+++ b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
@@ -10,9 +10,11 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog.h"
 #include "chrome/browser/ui/views/payments/payment_request_views_util.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/payments/currency_formatter.h"
 #include "components/payments/payment_request.h"
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -38,12 +40,16 @@
   columns->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER,
                      0, views::GridLayout::USE_PREF, 0, 0);
 
+  CurrencyFormatter* formatter = request()->GetOrCreateCurrencyFormatter(
+      request()->details()->total->amount->currency,
+      request()->details()->total->amount->currencySystem,
+      g_browser_process->GetApplicationLocale());
   layout->StartRow(0, 0);
   layout->AddView(new views::Label(l10n_util::GetStringFUTF16(
       IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_TOTAL_FORMAT,
-      base::ASCIIToUTF16(request()->details()->total->label),
-      base::ASCIIToUTF16(request()->details()->total->amount->value),
-      base::ASCIIToUTF16(request()->details()->total->amount->currency))));
+      base::UTF8ToUTF16(request()->details()->total->label),
+      base::UTF8ToUTF16(request()->details()->total->amount->currency),
+      formatter->Format(request()->details()->total->amount->value))));
 
   return payments::CreatePaymentView(
       CreateSheetHeaderView(
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index d085b26..433fa50d 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -9,9 +9,11 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog.h"
 #include "chrome/browser/ui/views/payments/payment_request_views_util.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/payments/currency_formatter.h"
 #include "components/payments/payment_request.h"
 #include "components/strings/grit/components_strings.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -157,11 +159,15 @@
 
 std::unique_ptr<views::View>
 PaymentSheetViewController::CreateOrderSummarySectionContent() {
+  CurrencyFormatter* formatter = request()->GetOrCreateCurrencyFormatter(
+      request()->details()->total->amount->currency,
+      request()->details()->total->amount->currencySystem,
+      g_browser_process->GetApplicationLocale());
   base::string16 label_value = l10n_util::GetStringFUTF16(
       IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_TOTAL_FORMAT,
-      base::ASCIIToUTF16(request()->details()->total->label),
-      base::ASCIIToUTF16(request()->details()->total->amount->currency),
-      base::ASCIIToUTF16(request()->details()->total->amount->value));
+      base::UTF8ToUTF16(request()->details()->total->label),
+      base::UTF8ToUTF16(request()->details()->total->amount->currency),
+      formatter->Format(request()->details()->total->amount->value));
 
   return base::MakeUnique<views::Label>(label_value);
 }
diff --git a/chrome/browser/webshare/share_service_impl.cc b/chrome/browser/webshare/share_service_impl.cc
index a5d57427..6b12400 100644
--- a/chrome/browser/webshare/share_service_impl.cc
+++ b/chrome/browser/webshare/share_service_impl.cc
@@ -4,8 +4,44 @@
 
 #include "chrome/browser/webshare/share_service_impl.h"
 
-#include "base/memory/ptr_util.h"
+#include <algorithm>
+#include <functional>
+#include <utility>
+
+#include "base/strings/string_util.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
+#include "net/base/escape.h"
+
+namespace {
+
+// Determines whether a character is allowed in a URL template placeholder.
+bool IsIdentifier(char c) {
+  return base::IsAsciiAlpha(c) || base::IsAsciiDigit(c) || c == '-' || c == '_';
+}
+
+// Joins a std::vector<base::StringPiece> into a single std::string.
+// TODO(constantina): Implement a base::JoinString() that takes StringPieces.
+// i.e. move this to base/strings/string_util.h, and thoroughly test.
+std::string JoinString(const std::vector<base::StringPiece>& pieces) {
+  size_t total_size = 0;
+  for (const auto& piece : pieces) {
+    total_size += piece.size();
+  }
+  std::string joined_pieces;
+  joined_pieces.reserve(total_size);
+
+  for (const auto& piece : pieces) {
+    piece.AppendToString(&joined_pieces);
+  }
+  return joined_pieces;
+}
+
+}  // namespace
 
 // static
 void ShareServiceImpl::Create(blink::mojom::ShareServiceRequest request) {
@@ -13,11 +49,101 @@
                           std::move(request));
 }
 
+// static
+bool ShareServiceImpl::ReplacePlaceholders(base::StringPiece url_template,
+                                           base::StringPiece title,
+                                           base::StringPiece text,
+                                           const GURL& share_url,
+                                           std::string* url_template_filled) {
+  constexpr char kTitlePlaceholder[] = "title";
+  constexpr char kTextPlaceholder[] = "text";
+  constexpr char kUrlPlaceholder[] = "url";
+
+  std::map<base::StringPiece, std::string> placeholder_to_data;
+  placeholder_to_data[kTitlePlaceholder] =
+      net::EscapeQueryParamValue(title, false);
+  placeholder_to_data[kTextPlaceholder] =
+      net::EscapeQueryParamValue(text, false);
+  placeholder_to_data[kUrlPlaceholder] =
+      net::EscapeQueryParamValue(share_url.spec(), false);
+
+  std::vector<base::StringPiece> split_template;
+  bool last_saw_open = false;
+  size_t start_index_to_copy = 0;
+  for (size_t i = 0; i < url_template.size(); ++i) {
+    if (last_saw_open) {
+      if (url_template[i] == '}') {
+        base::StringPiece placeholder = url_template.substr(
+            start_index_to_copy + 1, i - 1 - start_index_to_copy);
+        auto it = placeholder_to_data.find(placeholder);
+        if (it != placeholder_to_data.end()) {
+          // Replace the placeholder text with the parameter value.
+          split_template.push_back(it->second);
+        }
+
+        last_saw_open = false;
+        start_index_to_copy = i + 1;
+      } else if (!IsIdentifier(url_template[i])) {
+        // Error: Non-identifier character seen after open.
+        return false;
+      }
+    } else {
+      if (url_template[i] == '}') {
+        // Error: Saw close, with no corresponding open.
+        return false;
+      } else if (url_template[i] == '{') {
+        split_template.push_back(
+            url_template.substr(start_index_to_copy, i - start_index_to_copy));
+
+        last_saw_open = true;
+        start_index_to_copy = i;
+      }
+    }
+  }
+  if (last_saw_open) {
+    // Error: Saw open that was never closed.
+    return false;
+  }
+  split_template.push_back(url_template.substr(
+      start_index_to_copy, url_template.size() - start_index_to_copy));
+
+  *url_template_filled = JoinString(split_template);
+  return true;
+}
+
+void ShareServiceImpl::OpenTargetURL(const GURL& target_url) {
+// TODO(constantina): Prevent this code from being run/compiled in android.
+#if defined(OS_LINUX) || defined(OS_WIN)
+  Browser* browser = BrowserList::GetInstance()->GetLastActive();
+  chrome::AddTabAt(browser, target_url,
+                   browser->tab_strip_model()->active_index() + 1, true);
+#endif
+}
+
 void ShareServiceImpl::Share(const std::string& title,
                              const std::string& text,
-                             const GURL& url,
+                             const GURL& share_url,
                              const ShareCallback& callback) {
-  // TODO(constantina): Implement Web Share Target here.
-  NOTIMPLEMENTED();
-  callback.Run(base::Optional<std::string>("Not implemented: navigator.share"));
+  // TODO(constantina): replace hard-coded URL with one from user-chosen site.
+  constexpr char kUrlBase[] = "https://wicg.github.io/web-share-target/";
+  constexpr char kUrlTemplate[] =
+      "demos/sharetarget.html?title={title}&text={text}&url={url}";
+
+  std::string url_template_filled;
+  if (!ReplacePlaceholders(kUrlTemplate, title, text, share_url,
+                           &url_template_filled)) {
+    callback.Run(base::Optional<std::string>(
+        "Error: unable to replace placeholders in url template"));
+    return;
+  }
+
+  GURL target_url(kUrlBase + url_template_filled);
+  if (!target_url.is_valid()) {
+    callback.Run(base::Optional<std::string>(
+        "Error: url of share target is not a valid url."));
+    return;
+  }
+  OpenTargetURL(target_url);
+
+  callback.Run(base::nullopt);
 }
diff --git a/chrome/browser/webshare/share_service_impl.h b/chrome/browser/webshare/share_service_impl.h
index 83de10f..8bd381f7 100644
--- a/chrome/browser/webshare/share_service_impl.h
+++ b/chrome/browser/webshare/share_service_impl.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "base/gtest_prod_util.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "third_party/WebKit/public/platform/modules/webshare/webshare.mojom.h"
 
@@ -20,12 +21,33 @@
 
   static void Create(mojo::InterfaceRequest<ShareService> request);
 
+  // blink::mojom::ShareService overrides:
   void Share(const std::string& title,
              const std::string& text,
-             const GURL& url,
+             const GURL& share_url,
              const ShareCallback& callback) override;
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(ShareServiceImplUnittest, ReplacePlaceholders);
+
+  // Opens a new tab and navigates to |target_url|.
+  // Virtual for testing purposes.
+  virtual void OpenTargetURL(const GURL& target_url);
+
+  // Writes to |url_template_filled|, a copy of |url_template| with all
+  // instances of "{title}", "{text}", and "{url}" replaced with
+  // |title|, |text|, and |url| respectively.
+  // Replaces instances of "{X}" where "X" is any string besides "title",
+  // "text", and "url", with an empty string, for forwards compatibility.
+  // Returns false, if there are badly nested placeholders.
+  // This includes any case in which two "{" occur before a "}", or a "}"
+  // occurs with no preceding "{".
+  static bool ReplacePlaceholders(base::StringPiece url_template,
+                                  base::StringPiece title,
+                                  base::StringPiece text,
+                                  const GURL& share_url,
+                                  std::string* url_template_filled);
+
   DISALLOW_COPY_AND_ASSIGN(ShareServiceImpl);
 };
 
diff --git a/chrome/browser/webshare/share_service_impl_unittest.cc b/chrome/browser/webshare/share_service_impl_unittest.cc
index ae8b258..aba1777 100644
--- a/chrome/browser/webshare/share_service_impl_unittest.cc
+++ b/chrome/browser/webshare/share_service_impl_unittest.cc
@@ -2,55 +2,299 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <memory>
+
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/run_loop.h"
 #include "chrome/browser/webshare/share_service_impl.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
-class ShareServiceTest : public ChromeRenderViewHostTestHarness {
+namespace {
+
+constexpr char kTitle[] = "My title";
+constexpr char kText[] = "My text";
+constexpr char kUrlSpec[] = "https://www.google.com/";
+
+class ShareServiceTestImpl : public ShareServiceImpl {
  public:
-  ShareServiceTest() = default;
-  ~ShareServiceTest() override = default;
+  static ShareServiceTestImpl* Create(
+      blink::mojom::ShareServiceRequest request) {
+    std::unique_ptr<ShareServiceTestImpl> share_service_helper =
+        base::MakeUnique<ShareServiceTestImpl>();
+    ShareServiceTestImpl* share_service_helper_raw = share_service_helper.get();
+    mojo::MakeStrongBinding(std::move(share_service_helper),
+                            std::move(request));
+    return share_service_helper_raw;
+  }
+
+  const std::string& GetLastUsedTargetURL() { return last_used_target_url_; }
+
+ private:
+  std::string last_used_target_url_;
+
+  void OpenTargetURL(const GURL& target_url) override {
+    last_used_target_url_ = target_url.spec();
+  }
+};
+
+class ShareServiceImplUnittest : public ChromeRenderViewHostTestHarness {
+ public:
+  ShareServiceImplUnittest() = default;
+  ~ShareServiceImplUnittest() override = default;
 
   void SetUp() override {
     ChromeRenderViewHostTestHarness::SetUp();
 
-    ShareServiceImpl::Create(mojo::MakeRequest(&share_service_));
+    share_service_helper_ =
+        ShareServiceTestImpl::Create(mojo::MakeRequest(&share_service_));
   }
 
-  void TearDown() override {
-    ChromeRenderViewHostTestHarness::TearDown();
-  }
+  void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); }
 
-  void DidShare(const base::Optional<std::string>& expected,
-                const base::Optional<std::string>& str) {
-    EXPECT_EQ(expected, str);
+  void DidShare(const std::string& expected_target_url,
+                const base::Optional<std::string>& expected_param,
+                const base::Optional<std::string>& param) {
+    EXPECT_EQ(expected_param, param);
+    std::string target_url = share_service_helper_->GetLastUsedTargetURL();
+    EXPECT_EQ(expected_target_url, target_url);
 
     if (!on_callback_.is_null())
       on_callback_.Run();
   }
 
   blink::mojom::ShareServicePtr share_service_;
+  ShareServiceTestImpl* share_service_helper_;
   base::Closure on_callback_;
 };
 
+}  // namespace
+
 // Basic test to check the Share method calls the callback with the expected
 // parameters.
-TEST_F(ShareServiceTest, ShareCallbackParams) {
-  const GURL url("https://www.google.com");
+TEST_F(ShareServiceImplUnittest, ShareCallbackParams) {
+  std::string expected_url =
+      "https://wicg.github.io/web-share-target/demos/"
+      "sharetarget.html?title=My%20title&text=My%20text&url=https%3A%2F%2Fwww."
+      "google.com%2F";
+
+  const GURL url(kUrlSpec);
+  base::Callback<void(const base::Optional<std::string>&)> callback =
+      base::Bind(&ShareServiceImplUnittest::DidShare, base::Unretained(this),
+                 expected_url, base::Optional<std::string>());
 
   base::RunLoop run_loop;
   on_callback_ = run_loop.QuitClosure();
 
-  base::Callback<void(const base::Optional<std::string>&)> callback =
-      base::Bind(
-          &ShareServiceTest::DidShare, base::Unretained(this),
-          base::Optional<std::string>("Not implemented: navigator.share"));
-  share_service_->Share("title", "text", url, callback);
+  share_service_->Share(kTitle, kText, url, callback);
 
   run_loop.Run();
 }
+
+// Replace various numbers of placeholders in various orders. Placeholders are
+// adjacent to eachother; there are no padding characters.
+TEST_F(ShareServiceImplUnittest, ReplacePlaceholders) {
+  const GURL url(kUrlSpec);
+  std::string url_template_filled;
+  bool succeeded;
+
+  // No placeholders
+  std::string url_template = "blank";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("blank", url_template_filled);
+
+  // Empty |url_template|
+  url_template = "";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("", url_template_filled);
+
+  // One title placeholder.
+  url_template = "{title}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("My%20title", url_template_filled);
+
+  // One text placeholder.
+  url_template = "{text}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("My%20text", url_template_filled);
+
+  // One url placeholder.
+  url_template = "{url}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("https%3A%2F%2Fwww.google.com%2F", url_template_filled);
+
+  // One of each placeholder, in title, text, url order.
+  url_template = "{title}{text}{url}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("My%20titleMy%20texthttps%3A%2F%2Fwww.google.com%2F",
+            url_template_filled);
+
+  // One of each placeholder, in url, text, title order.
+  url_template = "{url}{text}{title}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("https%3A%2F%2Fwww.google.com%2FMy%20textMy%20title",
+            url_template_filled);
+
+  // Two of each placeholder, some next to each other, others not.
+  url_template = "{title}{url}{text}{text}{title}{url}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ(
+      "My%20titlehttps%3A%2F%2Fwww.google.com%2FMy%20textMy%20textMy%20"
+      "titlehttps%3A%2F%2Fwww.google.com%2F",
+      url_template_filled);
+
+  // Placeholders are in a query string, as values. The expected use case.
+  // Two of each placeholder, some next to each other, others not.
+  url_template =
+      "?title={title}&url={url}&text={text}&text={text}&"
+      "title={title}&url={url}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ(
+      "?title=My%20title&url=https%3A%2F%2Fwww.google.com%2F&text=My%20text&"
+      "text=My%20text&title=My%20title&url=https%3A%2F%2Fwww.google.com%2F",
+      url_template_filled);
+
+  // Badly nested placeholders.
+  url_template = "{";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_FALSE(succeeded);
+
+  url_template = "{title";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_FALSE(succeeded);
+
+  url_template = "{title{text}}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_FALSE(succeeded);
+
+  url_template = "{title{}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_FALSE(succeeded);
+
+  url_template = "{title}}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_FALSE(succeeded);
+
+  // Placeholder with non-identifier character.
+  url_template = "{title?}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_FALSE(succeeded);
+
+  // Placeholder with digit character.
+  url_template = "{title1}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("", url_template_filled);
+
+  // Empty placeholder.
+  url_template = "{}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("", url_template_filled);
+
+  // Unexpected placeholders.
+  url_template = "{nonexistentplaceholder}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("", url_template_filled);
+
+  // |url_template| with % escapes.
+  url_template = "%20{title}%20";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(url_template, kTitle, kText,
+                                                    url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("%20My%20title%20", url_template_filled);
+
+  // Share data that contains percent escapes.
+  url_template = "{title}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(
+      url_template, "My%20title", kText, url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("My%2520title", url_template_filled);
+
+  // Share data that contains placeholders. These should not be replaced.
+  url_template = "{title}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(
+      url_template, "{title}", kText, url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("%7Btitle%7D", url_template_filled);
+
+  // All characters that shouldn't be escaped.
+  url_template = "{title}";
+  succeeded =
+      ShareServiceImpl::ReplacePlaceholders(url_template,
+                                            "-_.!~*'()0123456789"
+                                            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                            "abcdefghijklmnopqrstuvwxyz",
+                                            kText, url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ(
+      "-_.!~*'()0123456789"
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+      "abcdefghijklmnopqrstuvwxyz",
+      url_template_filled);
+
+  // All characters that should be escaped.
+  url_template = "{title}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(
+      url_template, " \"#$%&+,/:;<=>?@[\\]^`{|}", kText, url,
+      &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ(
+      "%20%22%23%24%25%26%2B%2C%2F%3A%3B%3C%3D%3E%3F%40%5B%5C%5D%5E%60%7B%7C%"
+      "7D",
+      url_template_filled);
+
+  // Unicode chars.
+  // U+263B
+  url_template = "{title}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(
+      url_template, "\xe2\x98\xbb", kText, url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("%E2%98%BB", url_template_filled);
+
+  // U+00E9
+  url_template = "{title}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(
+      url_template, "\xc3\xa9", kText, url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("%C3%A9", url_template_filled);
+
+  // U+1F4A9
+  url_template = "{title}";
+  succeeded = ShareServiceImpl::ReplacePlaceholders(
+      url_template, "\xf0\x9f\x92\xa9", kText, url, &url_template_filled);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ("%F0%9F%92%A9", url_template_filled);
+}
diff --git a/chrome/common/extensions/docs/templates/articles/app_usb.html b/chrome/common/extensions/docs/templates/articles/app_usb.html
index 3a1e9d3..9c8bb8fe 100644
--- a/chrome/common/extensions/docs/templates/articles/app_usb.html
+++ b/chrome/common/extensions/docs/templates/articles/app_usb.html
@@ -42,8 +42,8 @@
 </p>
 <p>
   You must declare the VID/PID pairs for each type of device you want to use
-  under the "usbDevices" permission in your app's manifest file, as shown in the
-  example below:</p>
+  under the <code>usbDevices</code> permission in your app's manifest file, as
+  shown in the example below:</p>
 
 <pre data-filename="manifest.json">
 "permissions": [
@@ -61,6 +61,56 @@
 <p class="note">Note that only decimal numbers are allowed in JSON format.
   You cannot use hexadecimal numbers in these fields.</p>
 
+<p>Since <b>Chrome 57</b>, the requirement for declaring all the device types
+  in the app manifest is relaxed for apps running as Chrome OS
+  <a href="apps/manifest/kiosk_enabled">kiosk apps</a>.
+  For kiosk apps, you can use the <code>interfaceClass</code> permission
+  property to request permission to access USB devices that:
+  <ul>
+    <li>implement a USB interface of a specific interface class</li>
+    <li>have a specific USB device class</li>
+  </ul>
+  For example, the following <code>usbDevices</code> permission would grant an
+  app access to all USB devices that implement a printer interface (interface
+  class code 7), and to USB hub devices (device class code 9):</p>
+
+<pre data-filename="manifest.json">
+"permissions": [
+  {
+    "usbDevices": [
+      {"interfaceClass": 7},
+      {"interfaceClass": 9}
+    ]
+  }
+]
+</pre>
+
+<p>For the list of acceptable <code>interfaceClass</code> values, see
+  <a href="http://www.usb.org/developers/defined_class">USB Class Codes</a>.
+  </p>
+
+<p>The <code>interfaceClass</code> property can be combined with the
+  <code>vendorId</code> property to get access only to USB devices from a
+  specific vendor, as demonstrated by the following example:</p>
+
+<pre data-filename="manifest.json">
+"permissions": [
+  {
+    "usbDevices": [
+      {
+        "vendorId": 123,
+        "interfaceClass": 7
+      }
+    ]
+  }
+]
+</pre>
+
+<p class="note">Note that <code>usbDevices</code> permissions with
+  <code>interfaceClass</code> property have effect only when the app is running
+  in kiosk session - outside a kiosk session these permissions will be ignored.
+  </p>
+
 <h2 id="finding_device">Finding a device</h2>
 
 <p>
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc
index 881ff77..dc649f0 100644
--- a/chrome/renderer/chrome_render_frame_observer.cc
+++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -121,7 +121,7 @@
   if (!command_line.HasSwitch(switches::kDisableClientSidePhishingDetection))
     OnSetClientSidePhishingDetection(true);
   translate_helper_ = new translate::TranslateHelper(
-      render_frame, chrome::ISOLATED_WORLD_ID_TRANSLATE, 0,
+      render_frame, chrome::ISOLATED_WORLD_ID_TRANSLATE,
       extensions::kExtensionScheme);
 }
 
diff --git a/chrome/renderer/translate/translate_helper_browsertest.cc b/chrome/renderer/translate/translate_helper_browsertest.cc
index c0cda89..1284c32 100644
--- a/chrome/renderer/translate/translate_helper_browsertest.cc
+++ b/chrome/renderer/translate/translate_helper_browsertest.cc
@@ -70,7 +70,6 @@
   explicit TestTranslateHelper(content::RenderFrame* render_frame)
       : translate::TranslateHelper(render_frame,
                                    chrome::ISOLATED_WORLD_ID_TRANSLATE,
-                                   0,
                                    extensions::kExtensionScheme) {}
 
   base::TimeDelta AdjustDelay(int delayInMs) override {
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/InfoBarUtil.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/InfoBarUtil.java
index 83a3c5f..f1524a4 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/InfoBarUtil.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/InfoBarUtil.java
@@ -9,6 +9,10 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.infobar.InfoBar;
+import org.chromium.content.browser.test.util.Criteria;
+import org.chromium.content.browser.test.util.CriteriaHelper;
+
+import java.util.List;
 
 /**
  * Utility functions for dealing with InfoBars.
@@ -71,4 +75,16 @@
     public static boolean clickSecondaryButton(InfoBar infoBar) {
         return findButton(infoBar, R.id.button_secondary, true);
     }
+
+    /**
+     * Waits until the specified InfoBar list contains no info bars.
+     */
+    public static void waitUntilNoInfoBarsExist(final List<InfoBar> infoBars) {
+        CriteriaHelper.pollUiThread(new Criteria() {
+            @Override
+            public boolean isSatisfied() {
+                return infoBars.isEmpty();
+            }
+        });
+    }
 }
diff --git a/chrome/test/data/webui/md_bookmarks/store_test.js b/chrome/test/data/webui/md_bookmarks/store_test.js
index ebc1563..a1cf7e0e 100644
--- a/chrome/test/data/webui/md_bookmarks/store_test.js
+++ b/chrome/test/data/webui/md_bookmarks/store_test.js
@@ -32,19 +32,21 @@
     assertEquals(TEST_TREE.children[2], store.idToNodeMap_['5']);
   });
 
-  test('changing selectedId changes the selectedNode', function(){
+  test('changing selectedId changes the displayedList', function(){
     store.selectedId = '0';
-    assertEquals(TEST_TREE, store.selectedNode);
+    assertEquals(TEST_TREE.children, store.displayedList);
     store.selectedId = '1';
-    assertEquals(TEST_TREE.children[0], store.selectedNode);
+    assertEquals(TEST_TREE.children[0].children, store.displayedList);
     store.selectedId = '2';
-    assertEquals(TEST_TREE.children[0].children[0], store.selectedNode);
+    assertEquals(
+        TEST_TREE.children[0].children[0].children, store.displayedList);
     store.selectedId = '3';
-    assertEquals(TEST_TREE.children[0].children[1], store.selectedNode);
+    assertEquals(
+        TEST_TREE.children[0].children[1].children, store.displayedList);
     store.selectedId = '4';
-    assertEquals(TEST_TREE.children[1], store.selectedNode);
+    assertEquals(TEST_TREE.children[1].children, store.displayedList);
     store.selectedId = '5';
-    assertEquals(TEST_TREE.children[2], store.selectedNode);
+    assertEquals(TEST_TREE.children[2].children, store.displayedList);
   });
 
   test('correct paths generated for nodes', function() {
@@ -168,6 +170,39 @@
     assertEquals('0', store.selectedId);
   });
 
+  test('displayedList updates after searchTerm changes', function() {
+      var SEARCH_RESULTS = [
+        'cat',
+        'apple',
+        'Paris',
+      ];
+
+      chrome.bookmarks.search = function(searchTerm, callback) {
+        callback(SEARCH_RESULTS);
+      };
+
+      // Search for a non-empty string.
+      store.searchTerm = 'a';
+      assertFalse(store.rootNode.children[0].isSelected);
+      assertEquals(null, store.selectedId);
+      assertEquals(SEARCH_RESULTS, store.displayedList);
+
+      // Clear the searchTerm.
+      store.searchTerm = '';
+      var defaultFolder = store.rootNode.children[0];
+      assertTrue(defaultFolder.isSelected);
+      assertEquals(defaultFolder.id, store.selectedId);
+      assertEquals(defaultFolder.children, store.displayedList);
+
+      // Search with no bookmarks returned.
+      var EMPTY_RESULT = [];
+      chrome.bookmarks.search = function(searchTerm, callback) {
+        callback(EMPTY_RESULT);
+      };
+      store.searchTerm = 'asdf';
+      assertEquals(EMPTY_RESULT, store.displayedList);
+  });
+
   test('bookmark gets updated after editing', function() {
     // Edit title updates idToNodeMap_ properly.
     store.onBookmarkChanged_('4', {'title': 'test'});
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 30a179c..854448d 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-9161.0.0
\ No newline at end of file
+9177.0.0
\ No newline at end of file
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc
index 3ff9218c..064d0aa4 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc
@@ -254,20 +254,26 @@
   }
 
   void SetUp() override {
-    // Only use the primary data reduction proxy in order to make it easier to
-    // test bypassed bytes due to proxy fallbacks. This way, a test just needs
-    // to cause one proxy fallback in order for the data reduction proxy to be
-    // fully bypassed.
-    drp_test_context_ =
-        DataReductionProxyTestContext::Builder()
-            .WithParamsFlags(DataReductionProxyParams::kAllowed)
-            .WithURLRequestContext(&context_)
-            .WithMockClientSocketFactory(&mock_socket_factory_)
-            .Build();
+    drp_test_context_ = DataReductionProxyTestContext::Builder()
+                            .WithParamsFlags(0)
+                            .WithURLRequestContext(&context_)
+                            .WithMockClientSocketFactory(&mock_socket_factory_)
+                            .Build();
     drp_test_context_->AttachToURLRequestContext(&context_storage_);
     context_.set_client_socket_factory(&mock_socket_factory_);
     proxy_delegate_ = drp_test_context_->io_data()->CreateProxyDelegate();
     context_.set_proxy_delegate(proxy_delegate_.get());
+
+    // Only use the primary data reduction proxy in order to make it easier to
+    // test bypassed bytes due to proxy fallbacks. This way, a test just needs
+    // to cause one proxy fallback in order for the data reduction proxy to be
+    // fully bypassed.
+    std::vector<DataReductionProxyServer> data_reduction_proxy_servers;
+    data_reduction_proxy_servers.push_back(DataReductionProxyServer(
+        net::ProxyServer::FromURI(config()->test_params()->DefaultOrigin(),
+                                  net::ProxyServer::SCHEME_HTTP),
+        ProxyServer::CORE));
+    config()->test_params()->SetProxiesForHttp(data_reduction_proxy_servers);
   }
 
   // Create and execute a fake request using the data reduction proxy stack.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
index d0974d90..be76a72 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -388,9 +388,6 @@
       new SecureProxyChecker(basic_url_request_context_getter));
   warmup_url_fetcher_.reset(new WarmupURLFetcher(url_request_context_getter));
 
-  if (!config_values_->allowed())
-    return;
-
   PopulateAutoLoFiParams();
   AddDefaultProxyBypassRules();
   net::NetworkChangeNotifier::AddIPAddressObserver(this);
@@ -694,11 +691,6 @@
   return false;
 }
 
-// Returns true if the Data Reduction Proxy configuration may be used.
-bool DataReductionProxyConfig::allowed() const {
-  return config_values_->allowed();
-}
-
 // Returns true if the Data Reduction Proxy promo may be shown. This is not
 // tied to whether the Data Reduction Proxy is enabled.
 bool DataReductionProxyConfig::promo_allowed() const {
@@ -801,7 +793,6 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   if (enabled_by_user_) {
-    DCHECK(config_values_->allowed());
     RecordNetworkChangeEvent(IP_CHANGED);
 
     // Reset |network_quality_at_last_query_| to prevent recording of network
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
index 3fe9f61..6cad47d 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
@@ -179,9 +179,6 @@
   virtual bool ContainsDataReductionProxy(
       const net::ProxyConfig::ProxyRules& proxy_rules) const;
 
-  // Returns true if the Data Reduction Proxy configuration may be used.
-  bool allowed() const;
-
   // Returns true if the Data Reduction Proxy promo may be shown. This is not
   // tied to whether the Data Reduction Proxy is enabled.
   bool promo_allowed() const;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
index 43e94116..4136483 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -94,24 +94,15 @@
                         .WithMockDataReductionProxyService()
                         .Build();
 
-    ResetSettings(true, true, true, false);
+    ResetSettings(true, false);
 
     expected_params_.reset(new TestDataReductionProxyParams(
-        DataReductionProxyParams::kAllowed |
-            DataReductionProxyParams::kFallbackAllowed |
-            DataReductionProxyParams::kPromoAllowed,
+        DataReductionProxyParams::kPromoAllowed,
         TestDataReductionProxyParams::HAS_EVERYTHING));
   }
 
-  void ResetSettings(bool allowed,
-                     bool fallback_allowed,
-                     bool promo_allowed,
-                     bool holdback) {
+  void ResetSettings(bool promo_allowed, bool holdback) {
     int flags = 0;
-    if (allowed)
-      flags |= DataReductionProxyParams::kAllowed;
-    if (fallback_allowed)
-      flags |= DataReductionProxyParams::kFallbackAllowed;
     if (promo_allowed)
       flags |= DataReductionProxyParams::kPromoAllowed;
     if (holdback)
@@ -233,7 +224,7 @@
       "insecure_origin.net:80", net::ProxyServer::SCHEME_HTTP);
   SetProxiesForHttpOnCommandLine({kHttpsProxy, kHttpProxy});
 
-  ResetSettings(true, true, true, true);
+  ResetSettings(true, true);
 
   config()->UpdateConfigForTesting(true, false);
   config()->ReloadConfig();
@@ -248,7 +239,7 @@
       "insecure_origin.net:80", net::ProxyServer::SCHEME_HTTP);
 
   SetProxiesForHttpOnCommandLine({kHttpsProxy, kHttpProxy});
-  ResetSettings(true, true, true, false);
+  ResetSettings(true, false);
 
   // The proxy is enabled initially.
   config()->UpdateConfigForTesting(true, true);
@@ -359,7 +350,7 @@
     base::HistogramTester histogram_tester;
     SetProxiesForHttpOnCommandLine({kHttpsProxy, kHttpProxy});
 
-    ResetSettings(true, true, true, false);
+    ResetSettings(true, false);
 
     variations::testing::ClearAllVariationParams();
     std::map<std::string, std::string> variation_params;
@@ -376,9 +367,7 @@
 
     base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
     TestDataReductionProxyConfig config(
-        DataReductionProxyParams::kAllowed |
-            DataReductionProxyParams::kFallbackAllowed,
-        TestDataReductionProxyParams::HAS_EVERYTHING, task_runner(), nullptr,
+        0, TestDataReductionProxyParams::HAS_EVERYTHING, task_runner(), nullptr,
         configurator(), event_creator());
 
     scoped_refptr<net::URLRequestContextGetter> request_context_getter_ =
@@ -575,10 +564,6 @@
     rules.ParseFromString(proxy_rules);
 
     int flags = 0;
-    if (tests[i].allowed)
-      flags |= DataReductionProxyParams::kAllowed;
-    if (tests[i].fallback_allowed)
-      flags |= DataReductionProxyParams::kFallbackAllowed;
     unsigned int has_definitions = TestDataReductionProxyParams::HAS_EVERYTHING;
     std::unique_ptr<TestDataReductionProxyParams> params(
         new TestDataReductionProxyParams(flags, has_definitions));
@@ -621,8 +606,6 @@
   rules.ParseFromString(proxy_rules);
 
   int flags = 0;
-  flags |= DataReductionProxyParams::kAllowed;
-  flags |= DataReductionProxyParams::kFallbackAllowed;
   unsigned int has_definitions = TestDataReductionProxyParams::HAS_EVERYTHING;
   std::unique_ptr<TestDataReductionProxyParams> params(
       new TestDataReductionProxyParams(flags, has_definitions));
@@ -667,7 +650,6 @@
 TEST_F(DataReductionProxyConfigTest, IsDataReductionProxyWithParams) {
   const struct {
     net::ProxyServer proxy_server;
-    bool fallback_allowed;
     bool expected_result;
     net::ProxyServer expected_first;
     net::ProxyServer expected_second;
@@ -675,35 +657,23 @@
   } tests[] = {
       {net::ProxyServer::FromURI(TestDataReductionProxyParams::DefaultOrigin(),
                                  net::ProxyServer::SCHEME_HTTP),
-       true, true,
+       true,
        net::ProxyServer::FromURI(TestDataReductionProxyParams::DefaultOrigin(),
                                  net::ProxyServer::SCHEME_HTTP),
        net::ProxyServer::FromURI(
            TestDataReductionProxyParams::DefaultFallbackOrigin(),
            net::ProxyServer::SCHEME_HTTP),
        false},
-      {net::ProxyServer::FromURI(TestDataReductionProxyParams::DefaultOrigin(),
-                                 net::ProxyServer::SCHEME_HTTP),
-       false, true,
-       net::ProxyServer::FromURI(TestDataReductionProxyParams::DefaultOrigin(),
-                                 net::ProxyServer::SCHEME_HTTP),
-       net::ProxyServer(), false},
       {net::ProxyServer::FromURI(
            TestDataReductionProxyParams::DefaultFallbackOrigin(),
            net::ProxyServer::SCHEME_HTTP),
-       true, true, net::ProxyServer::FromURI(
-                       TestDataReductionProxyParams::DefaultFallbackOrigin(),
-                       net::ProxyServer::SCHEME_HTTP),
+       true, net::ProxyServer::FromURI(
+                 TestDataReductionProxyParams::DefaultFallbackOrigin(),
+                 net::ProxyServer::SCHEME_HTTP),
        net::ProxyServer(), true},
-      {net::ProxyServer::FromURI(
-           TestDataReductionProxyParams::DefaultFallbackOrigin(),
-           net::ProxyServer::SCHEME_HTTP),
-       false, false, net::ProxyServer(), net::ProxyServer(), false},
   };
   for (size_t i = 0; i < arraysize(tests); ++i) {
-    int flags = DataReductionProxyParams::kAllowed;
-    if (tests[i].fallback_allowed)
-      flags |= DataReductionProxyParams::kFallbackAllowed;
+    int flags = 0;
     unsigned int has_definitions = TestDataReductionProxyParams::HAS_EVERYTHING;
     std::unique_ptr<TestDataReductionProxyParams> params(
         new TestDataReductionProxyParams(flags, has_definitions));
@@ -1144,9 +1114,7 @@
   lofi_accuracy_recording_intervals.push_back(base::TimeDelta::FromSeconds(0));
 
   TestDataReductionProxyConfig config(
-      DataReductionProxyParams::kAllowed |
-          DataReductionProxyParams::kFallbackAllowed,
-      TestDataReductionProxyParams::HAS_EVERYTHING, task_runner(), nullptr,
+      0, TestDataReductionProxyParams::HAS_EVERYTHING, task_runner(), nullptr,
       configurator(), event_creator());
   config.SetLofiAccuracyRecordingIntervals(lofi_accuracy_recording_intervals);
   config.SetTickClock(tick_clock.get());
@@ -1234,9 +1202,7 @@
   lofi_accuracy_recording_intervals.push_back(base::TimeDelta::FromSeconds(1));
 
   TestDataReductionProxyConfig config(
-      DataReductionProxyParams::kAllowed |
-          DataReductionProxyParams::kFallbackAllowed,
-      TestDataReductionProxyParams::HAS_EVERYTHING, task_runner(), nullptr,
+      0, TestDataReductionProxyParams::HAS_EVERYTHING, task_runner(), nullptr,
       configurator(), event_creator());
   config.SetLofiAccuracyRecordingIntervals(lofi_accuracy_recording_intervals);
   config.SetTickClock(tick_clock.get());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
index c846d7263c..70390e3 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
@@ -113,7 +113,7 @@
   DataReductionProxyInterceptorTest() {
     test_context_ =
         DataReductionProxyTestContext::Builder()
-            .WithParamsFlags(DataReductionProxyParams::kAllowed)
+            .WithParamsFlags(0)
             .WithParamsDefinitions(TestDataReductionProxyParams::HAS_EVERYTHING)
             .Build();
     default_context_.reset(new TestURLRequestContextWithDataReductionProxy(
@@ -210,11 +210,10 @@
     ASSERT_TRUE(proxy_.Start());
     ASSERT_TRUE(direct_.Start());
 
-    test_context_ =
-        DataReductionProxyTestContext::Builder()
-            .WithParamsFlags(DataReductionProxyParams::kAllowed)
-            .WithURLRequestContext(&context_)
-            .Build();
+    test_context_ = DataReductionProxyTestContext::Builder()
+                        .WithParamsFlags(0)
+                        .WithURLRequestContext(&context_)
+                        .Build();
     std::string spec;
     base::TrimString(proxy_.GetURL("/").spec(), "/", &spec);
     net::ProxyServer origin =
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
index 0a56765..7b09403 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
@@ -101,10 +101,10 @@
 
 TEST_F(DataReductionProxyIODataTest, TestConstruction) {
   std::unique_ptr<DataReductionProxyIOData> io_data(
-      new DataReductionProxyIOData(
-          Client::UNKNOWN, DataReductionProxyParams::kAllowed, net_log(),
-          task_runner(), task_runner(), false /* enabled */,
-          std::string() /* user_agent */, std::string() /* channel */));
+      new DataReductionProxyIOData(Client::UNKNOWN, 0, net_log(), task_runner(),
+                                   task_runner(), false /* enabled */,
+                                   std::string() /* user_agent */,
+                                   std::string() /* channel */));
 
   // Check that the SimpleURLRequestContextGetter uses vanilla HTTP.
   net::URLRequestContext* request_context =
@@ -150,9 +150,7 @@
   net::TestURLRequestContext context(false);
   std::unique_ptr<DataReductionProxyTestContext> drp_test_context =
       DataReductionProxyTestContext::Builder()
-          .WithParamsFlags(DataReductionProxyParams::kAllowed |
-                           DataReductionProxyParams::kFallbackAllowed |
-                           DataReductionProxyParams::kPromoAllowed)
+          .WithParamsFlags(DataReductionProxyParams::kPromoAllowed)
           .WithURLRequestContext(&context)
           .SkipSettingsInitialization()
           .Build();
@@ -192,9 +190,7 @@
   net::TestURLRequestContext context(false);
   std::unique_ptr<DataReductionProxyTestContext> drp_test_context =
       DataReductionProxyTestContext::Builder()
-          .WithParamsFlags(DataReductionProxyParams::kAllowed |
-                           DataReductionProxyParams::kFallbackAllowed |
-                           DataReductionProxyParams::kPromoAllowed |
+          .WithParamsFlags(DataReductionProxyParams::kPromoAllowed |
                            DataReductionProxyParams::kHoldback)
           .WithURLRequestContext(&context)
           .SkipSettingsInitialization()
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
index 2aed779..da8d668 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
@@ -33,7 +33,7 @@
   base::MessageLoopForIO message_loop;
   std::unique_ptr<DataReductionProxyTestContext> test_context =
       DataReductionProxyTestContext::Builder()
-          .WithParamsFlags(DataReductionProxyParams::kAllowed)
+          .WithParamsFlags(0)
           .WithParamsDefinitions(TestDataReductionProxyParams::HAS_ORIGIN)
           .Build();
   TestDataReductionProxyConfig* config = test_context->config();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.cc
index fed1729d..905160c4 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.cc
@@ -18,8 +18,6 @@
       new DataReductionProxyMutableConfigValues());
   config_values->promo_allowed_ = params->promo_allowed();
   config_values->holdback_ = params->holdback();
-  config_values->allowed_ = params->allowed();
-  config_values->fallback_allowed_ = params->fallback_allowed();
   config_values->secure_proxy_check_url_ = params->secure_proxy_check_url();
   return config_values;
 }
@@ -27,8 +25,6 @@
 DataReductionProxyMutableConfigValues::DataReductionProxyMutableConfigValues()
     : promo_allowed_(false),
       holdback_(false),
-      allowed_(false),
-      fallback_allowed_(false),
       use_override_proxies_for_http_(false) {
   use_override_proxies_for_http_ =
       params::GetOverrideProxiesForHttpFromCommandLine(
@@ -50,14 +46,6 @@
   return holdback_;
 }
 
-bool DataReductionProxyMutableConfigValues::allowed() const {
-  return allowed_;
-}
-
-bool DataReductionProxyMutableConfigValues::fallback_allowed() const {
-  return fallback_allowed_;
-}
-
 const std::vector<DataReductionProxyServer>
 DataReductionProxyMutableConfigValues::proxies_for_http() const {
   DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.h
index ee75daf..18374527 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.h
@@ -42,8 +42,6 @@
   // Overrides of |DataReductionProxyConfigValues|
   bool promo_allowed() const override;
   bool holdback() const override;
-  bool allowed() const override;
-  bool fallback_allowed() const override;
   const std::vector<DataReductionProxyServer> proxies_for_http() const override;
   const GURL& secure_proxy_check_url() const override;
 
@@ -53,8 +51,6 @@
  private:
   bool promo_allowed_;
   bool holdback_;
-  bool allowed_;
-  bool fallback_allowed_;
   std::vector<DataReductionProxyServer> proxies_for_http_;
   GURL secure_proxy_check_url_;
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values_unittest.cc
index c6734e3..87537241 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values_unittest.cc
@@ -24,8 +24,7 @@
   ~DataReductionProxyMutableConfigValuesTest() override {}
 
   void Init() {
-    params_.reset(new DataReductionProxyParams(
-        DataReductionProxyParams::kAllowAllProxyConfigurations));
+    params_.reset(new DataReductionProxyParams(0));
     mutable_config_values_ =
         DataReductionProxyMutableConfigValues::CreateFromParams(params_.get());
   }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
index 32cb51db..40cc55ec0 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
@@ -134,8 +134,7 @@
   DataReductionProxyRequestOptionsTest() {
     test_context_ =
         DataReductionProxyTestContext::Builder()
-            .WithParamsFlags(
-                DataReductionProxyParams::kAllowAllProxyConfigurations)
+            .WithParamsFlags(0)
             .WithParamsDefinitions(TestDataReductionProxyParams::HAS_EVERYTHING)
             .Build();
   }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
index 4e6cb86..fecd6ea 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
@@ -52,7 +52,6 @@
 DataReductionProxySettings::DataReductionProxySettings()
     : unreachable_(false),
       deferred_initialization_(false),
-      allowed_(false),
       promo_allowed_(false),
       lo_fi_mode_active_(false),
       lo_fi_load_image_requested_(false),
@@ -69,8 +68,7 @@
 }
 
 DataReductionProxySettings::~DataReductionProxySettings() {
-  if (allowed_)
-    spdy_proxy_auth_enabled_.Destroy();
+  spdy_proxy_auth_enabled_.Destroy();
 }
 
 void DataReductionProxySettings::InitPrefMembers() {
@@ -83,7 +81,6 @@
 
 void DataReductionProxySettings::UpdateConfigValues() {
   DCHECK(config_);
-  allowed_ = config_->allowed();
   promo_allowed_ = config_->promo_allowed();
 }
 
@@ -144,10 +141,6 @@
 
 void DataReductionProxySettings::SetDataReductionProxyEnabled(bool enabled) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  // Prevent configuring the proxy when it is not allowed to be used.
-  if (!allowed_)
-    return;
-
   if (spdy_proxy_auth_enabled_.GetValue() != enabled) {
     spdy_proxy_auth_enabled_.SetValue(enabled);
     OnProxyEnabledPrefChange();
@@ -240,8 +233,6 @@
   if (!register_synthetic_field_trial_.is_null()) {
     RegisterDataReductionProxyFieldTrial();
   }
-  if (!allowed_)
-    return;
   MaybeActivateDataReductionProxy(false);
 }
 
@@ -330,20 +321,14 @@
 }
 
 // Metrics methods
-void DataReductionProxySettings::RecordDataReductionInit() {
+void DataReductionProxySettings::RecordDataReductionInit() const {
   DCHECK(thread_checker_.CalledOnValidThread());
-  ProxyStartupState state = PROXY_NOT_AVAILABLE;
-  if (allowed_) {
-    if (IsDataReductionProxyEnabled())
-      state = PROXY_ENABLED;
-    else
-      state = PROXY_DISABLED;
-  }
-
-  RecordStartupState(state);
+  RecordStartupState(IsDataReductionProxyEnabled() ? PROXY_ENABLED
+                                                   : PROXY_DISABLED);
 }
 
-void DataReductionProxySettings::RecordStartupState(ProxyStartupState state) {
+void DataReductionProxySettings::RecordStartupState(
+    ProxyStartupState state) const {
   UMA_HISTOGRAM_ENUMERATION(kUMAProxyStartupStateHistogram,
                             state,
                             PROXY_STARTUP_STATE_COUNT);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
index f522542..a258151 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
@@ -187,11 +187,6 @@
   // InitDataReductionProxySettings has not been called.
   DataReductionProxyEventStore* GetEventStore() const;
 
-  // Returns true if the data reduction proxy configuration may be used.
-  bool Allowed() const {
-    return allowed_;
-  }
-
   // Returns true if the data reduction proxy promo may be shown.
   // This is independent of whether the data reduction proxy is allowed.
   bool PromoAllowed() const {
@@ -224,12 +219,12 @@
 
   // Metrics method. Subclasses should override if they wish to provide
   // alternatives.
-  virtual void RecordDataReductionInit();
+  virtual void RecordDataReductionInit() const;
 
   // Virtualized for mocking. Records UMA specifying whether the proxy was
   // enabled or disabled at startup.
   virtual void RecordStartupState(
-      data_reduction_proxy::ProxyStartupState state);
+      data_reduction_proxy::ProxyStartupState state) const;
 
  private:
   friend class DataReductionProxySettingsTestBase;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
index 9b5fe4b..25e64a0 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
@@ -54,7 +54,7 @@
   pref_service->registry()->RegisterDictionaryPref(kProxy);
   pref_service->SetBoolean(prefs::kDataReductionProxyWasEnabledBefore, false);
 
-  ResetSettings(nullptr, true, true, true, false);
+  ResetSettings(nullptr, true, false);
 
   ListPrefUpdate original_update(test_context_->pref_service(),
                                  prefs::kDailyHttpOriginalContentLength);
@@ -74,15 +74,9 @@
 template <class C>
 void DataReductionProxySettingsTestBase::ResetSettings(
     std::unique_ptr<base::Clock> clock,
-    bool allowed,
-    bool fallback_allowed,
     bool promo_allowed,
     bool holdback) {
   int flags = 0;
-  if (allowed)
-    flags |= DataReductionProxyParams::kAllowed;
-  if (fallback_allowed)
-    flags |= DataReductionProxyParams::kFallbackAllowed;
   if (promo_allowed)
     flags |= DataReductionProxyParams::kPromoAllowed;
   if (holdback)
@@ -109,8 +103,6 @@
 // Explicitly generate required instantiations.
 template void DataReductionProxySettingsTestBase::ResetSettings<
     DataReductionProxySettings>(std::unique_ptr<base::Clock> clock,
-                                bool allowed,
-                                bool fallback_allowed,
                                 bool promo_allowed,
                                 bool holdback);
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
index 220d081..987de63 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
@@ -33,8 +33,7 @@
   }
   MOCK_METHOD0(GetOriginalProfilePrefs, PrefService*());
   MOCK_METHOD0(GetLocalStatePrefs, PrefService*());
-  MOCK_METHOD1(RecordStartupState,
-               void(ProxyStartupState state));
+  MOCK_CONST_METHOD1(RecordStartupState, void(ProxyStartupState state));
 };
 
 class DataReductionProxySettingsTestBase : public testing::Test {
@@ -42,9 +41,7 @@
   static void AddTestProxyToCommandLine();
 
   DataReductionProxySettingsTestBase();
-  DataReductionProxySettingsTestBase(bool allowed,
-                                     bool fallback_allowed,
-                                     bool promo_allowed);
+  DataReductionProxySettingsTestBase(bool promo_allowed);
   ~DataReductionProxySettingsTestBase() override;
 
   void AddProxyToCommandLine();
@@ -53,13 +50,9 @@
 
   template <class C>
   void ResetSettings(std::unique_ptr<base::Clock> clock,
-                     bool allowed,
-                     bool fallback_allowed,
                      bool promo_allowed,
                      bool holdback);
   virtual void ResetSettings(std::unique_ptr<base::Clock> clock,
-                             bool allowed,
-                             bool fallback_allowed,
                              bool promo_allowed,
                              bool holdback) = 0;
 
@@ -97,12 +90,10 @@
  public:
   typedef MockDataReductionProxySettings<C> MockSettings;
   void ResetSettings(std::unique_ptr<base::Clock> clock,
-                     bool allowed,
-                     bool fallback_allowed,
                      bool promo_allowed,
                      bool holdback) override {
     return DataReductionProxySettingsTestBase::ResetSettings<C>(
-        std::move(clock), allowed, fallback_allowed, promo_allowed, holdback);
+        std::move(clock), promo_allowed, holdback);
   }
 };
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
index dd162d19..d2ef437 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
@@ -651,7 +651,7 @@
   std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock());
   base::SimpleTestClock* clock_ptr = clock.get();
   clock_ptr->Advance(base::TimeDelta::FromDays(1));
-  ResetSettings(std::move(clock), true, true, false, false);
+  ResetSettings(std::move(clock), false, false);
 
   base::Time last_enabled_time = clock_ptr->Now();
 
@@ -735,7 +735,7 @@
   std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock());
   base::SimpleTestClock* clock_ptr = clock.get();
   clock_ptr->Advance(base::TimeDelta::FromDays(1));
-  ResetSettings(std::move(clock), true, true, false, false);
+  ResetSettings(std::move(clock), false, false);
 
   InitPrefMembers();
   base::HistogramTester histogram_tester;
@@ -771,27 +771,4 @@
   }
 }
 
-TEST_F(DataReductionProxySettingsTest, CheckInitMetricsWhenNotAllowed) {
-  // No call to |AddProxyToCommandLine()| was made, so the proxy feature
-  // should be unavailable.
-  // Clear the command line. Setting flags can force the proxy to be allowed.
-  base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
-
-  ResetSettings(nullptr, false, false, false, false);
-  MockSettings* settings = static_cast<MockSettings*>(settings_.get());
-  EXPECT_FALSE(settings->allowed_);
-  EXPECT_CALL(*settings, RecordStartupState(PROXY_NOT_AVAILABLE));
-
-  settings_->InitDataReductionProxySettings(
-      test_context_->GetDataReductionProxyEnabledPrefName(),
-      test_context_->pref_service(), test_context_->io_data(),
-      test_context_->CreateDataReductionProxyService(settings_.get()));
-  settings_->SetCallbackToRegisterSyntheticFieldTrial(
-      base::Bind(&DataReductionProxySettingsTestBase::
-                 SyntheticFieldTrialRegistrationCallback,
-                 base::Unretained(this)));
-
-  test_context_->RunUntilIdle();
-}
-
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
index 8ddf954..3b5cb25a 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -287,9 +287,7 @@
 }
 
 DataReductionProxyTestContext::Builder::Builder()
-    : params_flags_(DataReductionProxyParams::kAllowed |
-                    DataReductionProxyParams::kFallbackAllowed |
-                    DataReductionProxyParams::kPromoAllowed),
+    : params_flags_(DataReductionProxyParams::kPromoAllowed),
       params_definitions_(TestDataReductionProxyParams::HAS_EVERYTHING),
       client_(Client::UNKNOWN),
       request_context_(nullptr),
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h
index 28bc3f0..15c4579 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h
@@ -26,12 +26,6 @@
   // proxy if enabled.
   virtual bool holdback() const = 0;
 
-  // Returns true if the data reduction proxy configuration may be used.
-  virtual bool allowed() const = 0;
-
-  // Returns true if the fallback proxy may be used.
-  virtual bool fallback_allowed() const = 0;
-
   // Returns the HTTP proxy servers to be used.
   virtual const std::vector<DataReductionProxyServer> proxies_for_http()
       const = 0;
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
index 340c494..8b9433ca 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
@@ -388,14 +388,11 @@
 
 DataReductionProxyParams::DataReductionProxyParams(int flags,
                                                    bool should_call_init)
-    : allowed_((flags & kAllowed) == kAllowed),
-      fallback_allowed_((flags & kFallbackAllowed) == kFallbackAllowed),
-      promo_allowed_((flags & kPromoAllowed) == kPromoAllowed),
+    : promo_allowed_((flags & kPromoAllowed) == kPromoAllowed),
       holdback_((flags & kHoldback) == kHoldback),
-      configured_on_command_line_(false),
       use_override_proxies_for_http_(false) {
   if (should_call_init) {
-    bool result = Init(allowed_, fallback_allowed_);
+    bool result = Init();
     DCHECK(result);
   }
 }
@@ -405,39 +402,24 @@
   proxies_for_http_ = proxies_for_http;
 }
 
-bool DataReductionProxyParams::Init(bool allowed, bool fallback_allowed) {
+bool DataReductionProxyParams::Init() {
   InitWithoutChecks();
   // Verify that all necessary params are set.
-  if (allowed) {
-    if (!origin_.is_valid()) {
-      DVLOG(1) << "Invalid data reduction proxy origin: " << origin_.ToURI();
-      return false;
-    }
+  if (!origin_.is_valid()) {
+    DVLOG(1) << "Invalid data reduction proxy origin: " << origin_.ToURI();
+    return false;
   }
 
-  if (allowed && fallback_allowed) {
-    if (!fallback_origin_.is_valid()) {
-      DVLOG(1) << "Invalid data reduction proxy fallback origin: "
-          << fallback_origin_.ToURI();
-      return false;
-    }
+  if (!fallback_origin_.is_valid()) {
+    DVLOG(1) << "Invalid data reduction proxy fallback origin: "
+             << fallback_origin_.ToURI();
+    return false;
   }
 
-  if (allowed && !secure_proxy_check_url_.is_valid()) {
+  if (!secure_proxy_check_url_.is_valid()) {
     DVLOG(1) << "Invalid secure proxy check url: <null>";
     return false;
   }
-
-  if (fallback_allowed_ && !allowed_) {
-    DVLOG(1) << "The data reduction proxy fallback cannot be allowed if "
-        << "the data reduction proxy is not allowed";
-    return false;
-  }
-  if (promo_allowed_ && !allowed_) {
-    DVLOG(1) << "The data reduction proxy promo cannot be allowed if the "
-        << "data reduction proxy is not allowed";
-    return false;
-  }
   return true;
 }
 
@@ -454,14 +436,6 @@
   origin = command_line.GetSwitchValueASCII(switches::kDataReductionProxy);
   std::string fallback_origin =
       command_line.GetSwitchValueASCII(switches::kDataReductionProxyFallback);
-
-  configured_on_command_line_ = !(origin.empty() && fallback_origin.empty());
-
-  // Configuring the proxy on the command line overrides the values of
-  // |allowed_|.
-  if (configured_on_command_line_)
-    allowed_ = true;
-
   std::string secure_proxy_check_url = command_line.GetSwitchValueASCII(
       switches::kDataReductionProxySecureProxyCheckURL);
   std::string warmup_url = command_line.GetSwitchValueASCII(
@@ -484,7 +458,7 @@
     proxies_for_http_.push_back(
         DataReductionProxyServer(origin_, ProxyServer::CORE));
   }
-  if (fallback_allowed_ && fallback_origin_.is_valid()) {
+  if (fallback_origin_.is_valid()) {
     // |fallback| is also a core proxy server.
     proxies_for_http_.push_back(
         DataReductionProxyServer(fallback_origin_, ProxyServer::CORE));
@@ -506,16 +480,6 @@
   return secure_proxy_check_url_;
 }
 
-// Returns true if the data reduction proxy configuration may be used.
-bool DataReductionProxyParams::allowed() const {
-  return allowed_;
-}
-
-// Returns true if the fallback proxy may be used.
-bool DataReductionProxyParams::fallback_allowed() const {
-  return fallback_allowed_;
-}
-
 // Returns true if the data reduction proxy promo may be shown.
 // This is idependent of whether the data reduction proxy is allowed.
 // TODO(bengr): maybe tie to whether proxy is allowed.
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
index df63942..f7bdf3b 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
@@ -179,22 +179,13 @@
 // Reduction Proxy.
 class DataReductionProxyParams : public DataReductionProxyConfigValues {
  public:
-  // Flags used during construction that specify if the data reduction proxy
-  // is allowed to be used, if the fallback proxy is allowed to be used, if the
-  // promotion is allowed to be shown, and if this instance is part of a
-  // holdback experiment.
-  static const unsigned int kAllowed = (1 << 0);
-  static const unsigned int kFallbackAllowed = (1 << 1);
-  static const unsigned int kAllowAllProxyConfigurations =
-      kAllowed | kFallbackAllowed;
+  // Flags used during construction that specify if the promotion is allowed to
+  // be shown, and if this instance is part of a holdback experiment.
   static const unsigned int kPromoAllowed = (1 << 2);
   static const unsigned int kHoldback = (1 << 3);
 
-  // Constructs configuration parameters. If |kAllowed|, then the standard
-  // data reduction proxy configuration is allowed to be used. If
-  // |kfallbackAllowed| a fallback proxy can be used if the primary proxy is
-  // bypassed or disabled. Finally if |kPromoAllowed|, the client may show a
-  // promotion for the data reduction proxy.
+  // Constructs configuration parameters. If |kPromoAllowed|, the client may
+  // show a promotion for the data reduction proxy.
   //
   // A standard configuration has a primary proxy, and a fallback proxy for
   // HTTP traffic.
@@ -210,10 +201,6 @@
 
   const GURL& secure_proxy_check_url() const override;
 
-  bool allowed() const override;
-
-  bool fallback_allowed() const override;
-
   bool promo_allowed() const override;
 
   bool holdback() const override;
@@ -226,7 +213,7 @@
   // Initialize the values of the proxies, and secure proxy check URL, from
   // command line flags and preprocessor constants, and check that there are
   // corresponding definitions for the allowed configurations.
-  bool Init(bool allowed, bool fallback_allowed);
+  bool Init();
 
   // Initialize the values of the proxies, and secure proxy check URL from
   // command line flags and preprocessor constants.
@@ -246,13 +233,9 @@
 
   GURL secure_proxy_check_url_;
 
-  bool allowed_;
-  bool fallback_allowed_;
   bool promo_allowed_;
   bool holdback_;
 
-  bool configured_on_command_line_;
-
   bool use_override_proxies_for_http_;
   std::vector<DataReductionProxyServer> override_data_reduction_proxy_servers_;
 
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc
index 95c7213..3a68f3a 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc
@@ -20,8 +20,7 @@
     int flags, unsigned int has_definitions)
     : DataReductionProxyParams(flags, false),
       has_definitions_(has_definitions) {
-  init_result_ = Init(flags & DataReductionProxyParams::kAllowed,
-                      flags & DataReductionProxyParams::kFallbackAllowed);
+  init_result_ = Init();
   }
 
 bool TestDataReductionProxyParams::init_result() const {
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
index f6ddbe83..0d10608 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
@@ -27,12 +27,8 @@
  public:
   void CheckParams(const TestDataReductionProxyParams& params,
                    bool expected_init_result,
-                   bool expected_allowed,
-                   bool expected_fallback_allowed,
                    bool expected_promo_allowed) {
     EXPECT_EQ(expected_init_result, params.init_result());
-    EXPECT_EQ(expected_allowed, params.allowed());
-    EXPECT_EQ(expected_fallback_allowed, params.fallback_allowed());
     EXPECT_EQ(expected_promo_allowed, params.promo_allowed());
   }
   void CheckValues(const TestDataReductionProxyParams& params,
@@ -60,11 +56,9 @@
 
 TEST_F(DataReductionProxyParamsTest, EverythingDefined) {
   TestDataReductionProxyParams params(
-      DataReductionProxyParams::kAllowed |
-      DataReductionProxyParams::kFallbackAllowed |
       DataReductionProxyParams::kPromoAllowed,
       TestDataReductionProxyParams::HAS_EVERYTHING);
-  CheckParams(params, true, true, true, true);
+  CheckParams(params, true, true);
   std::vector<DataReductionProxyServer> expected_proxies;
 
   // Both the origin and fallback proxy must have type CORE.
@@ -94,11 +88,9 @@
       switches::kDataReductionProxySecureProxyCheckURL,
       TestDataReductionProxyParams::FlagSecureProxyCheckURL());
   TestDataReductionProxyParams params(
-      DataReductionProxyParams::kAllowed |
-      DataReductionProxyParams::kFallbackAllowed |
       DataReductionProxyParams::kPromoAllowed,
       TestDataReductionProxyParams::HAS_EVERYTHING);
-  CheckParams(params, true, true, true, true);
+  CheckParams(params, true, true);
   CheckValues(params, TestDataReductionProxyParams::FlagOrigin(),
               TestDataReductionProxyParams::FlagFallbackOrigin(),
               TestDataReductionProxyParams::FlagSecureProxyCheckURL());
@@ -107,53 +99,37 @@
 TEST_F(DataReductionProxyParamsTest, CarrierTestFlag) {
   static const char kCarrierTestOrigin[] =
       "http://o-o.preferred.nttdocomodcp-hnd1.proxy-dev.googlezip.net:80";
+  static const char kDefaultFallbackOrigin[] = "compress.googlezip.net:80";
   base::CommandLine::ForCurrentProcess()->InitFromArgv(0, nullptr);
   base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       switches::kEnableDataReductionProxyCarrierTest, kCarrierTestOrigin);
-  DataReductionProxyParams params(DataReductionProxyParams::kAllowed);
+  DataReductionProxyParams params(0);
   std::vector<DataReductionProxyServer> proxies_for_http;
   proxies_for_http.push_back(DataReductionProxyServer(
       net::ProxyServer::FromURI(kCarrierTestOrigin,
                                 net::ProxyServer::SCHEME_HTTP),
       ProxyServer::CORE));
+  proxies_for_http.push_back(DataReductionProxyServer(
+      net::ProxyServer::FromURI(kDefaultFallbackOrigin,
+                                net::ProxyServer::SCHEME_HTTP),
+      ProxyServer::CORE));
   EXPECT_EQ(params.proxies_for_http(), proxies_for_http);
 }
 
 TEST_F(DataReductionProxyParamsTest, InvalidConfigurations) {
   const struct {
-    bool allowed;
-    bool fallback_allowed;
     bool promo_allowed;
     unsigned int missing_definitions;
     bool expected_result;
   } tests[] = {
-      {true, true, true, TestDataReductionProxyParams::HAS_NOTHING, true},
-      {true, false, true, TestDataReductionProxyParams::HAS_NOTHING, true},
-      {false, true, true, TestDataReductionProxyParams::HAS_NOTHING, false},
-      {true, true, true, TestDataReductionProxyParams::HAS_ORIGIN, false},
-      {true, false, true, TestDataReductionProxyParams::HAS_ORIGIN, false},
-      {false, true, true, TestDataReductionProxyParams::HAS_ORIGIN, false},
-      {true, true, true, TestDataReductionProxyParams::HAS_NOTHING, true},
-      {true, false, true, TestDataReductionProxyParams::HAS_FALLBACK_ORIGIN,
-       true},
-      {false, true, true, TestDataReductionProxyParams::HAS_FALLBACK_ORIGIN,
-       false},
-      {true, true, true, TestDataReductionProxyParams::HAS_FALLBACK_ORIGIN,
-       false},
-      {true, true, true,
-       TestDataReductionProxyParams::HAS_SECURE_PROXY_CHECK_URL, false},
-      {true, false, true,
-       TestDataReductionProxyParams::HAS_SECURE_PROXY_CHECK_URL, false},
-      {false, true, true,
-       TestDataReductionProxyParams::HAS_SECURE_PROXY_CHECK_URL, false},
+      {true, TestDataReductionProxyParams::HAS_NOTHING, true},
+      {true, TestDataReductionProxyParams::HAS_ORIGIN, false},
+      {true, TestDataReductionProxyParams::HAS_FALLBACK_ORIGIN, false},
+      {true, TestDataReductionProxyParams::HAS_SECURE_PROXY_CHECK_URL, false},
   };
 
   for (size_t i = 0; i < arraysize(tests); ++i) {
     int flags = 0;
-    if (tests[i].allowed)
-      flags |= DataReductionProxyParams::kAllowed;
-    if (tests[i].fallback_allowed)
-      flags |= DataReductionProxyParams::kFallbackAllowed;
     if (tests[i].promo_allowed)
       flags |= DataReductionProxyParams::kPromoAllowed;
     TestDataReductionProxyParams params(
@@ -552,8 +528,7 @@
   base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       switches::kDataReductionProxyHttpProxies,
       "http://override-first.net;http://override-second.net");
-  DataReductionProxyParams params(
-      DataReductionProxyParams::kAllowAllProxyConfigurations);
+  DataReductionProxyParams params(0);
 
   // Overriding proxies must have type UNSPECIFIED_TYPE.
   std::vector<DataReductionProxyServer> expected_override_proxies_for_http;
diff --git a/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.cc b/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.cc
index 11e0bc4..73c6133 100644
--- a/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.cc
+++ b/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.cc
@@ -42,7 +42,6 @@
 
 void DistillerJsRenderFrameObserver::DidCreateScriptContext(
     v8::Local<v8::Context> context,
-    int extension_group,
     int world_id) {
   if (world_id != distiller_isolated_world_id_ || !is_distiller_page_) {
     return;
diff --git a/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h b/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h
index fb75189..93476b5 100644
--- a/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h
+++ b/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h
@@ -30,7 +30,6 @@
   void DidStartProvisionalLoad() override;
   void DidFinishLoad() override;
   void DidCreateScriptContext(v8::Local<v8::Context> context,
-                              int extension_group,
                               int world_id) override;
 
   // Add the mojo interface to a RenderFrame's
diff --git a/components/payments/BUILD.gn b/components/payments/BUILD.gn
index bbdd5f5..1cd2dc3 100644
--- a/components/payments/BUILD.gn
+++ b/components/payments/BUILD.gn
@@ -50,6 +50,8 @@
 
 static_library("payment_validation") {
   sources = [
+    "currency_formatter.cc",
+    "currency_formatter.h",
     "payment_details_validation.cc",
     "payment_details_validation.h",
     "payments_validators.cc",
@@ -62,16 +64,23 @@
     "//third_party/re2:re2",
     "//url:url",
   ]
+
+  public_deps = [
+    "//third_party/icu:icu",
+  ]
 }
 
-static_library("unit_tests") {
+source_set("unit_tests") {
   testonly = true
   sources = [
+    "currency_formatter_unittest.cc",
     "payments_validators_test.cc",
   ]
 
   deps = [
     ":payment_validation",
+    "//base",
     "//testing/gtest",
+    "//third_party/icu:icu",
   ]
 }
diff --git a/components/payments/currency_formatter.cc b/components/payments/currency_formatter.cc
new file mode 100644
index 0000000..f333787
--- /dev/null
+++ b/components/payments/currency_formatter.cc
@@ -0,0 +1,124 @@
+// 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 "components/payments/currency_formatter.h"
+
+#include <memory>
+
+#include "base/numerics/safe_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "third_party/icu/source/common/unicode/stringpiece.h"
+#include "third_party/icu/source/common/unicode/uchar.h"
+#include "third_party/icu/source/common/unicode/unistr.h"
+#include "third_party/icu/source/common/unicode/utypes.h"
+
+namespace payments {
+
+const char kIso4217CurrencySystem[] = "urn:iso:std:iso:4217";
+namespace {
+
+// Support a maximum of 10 fractional digits, similar to the ISO20022 standard.
+// https://www.iso20022.org/standardsrepository/public/wqt/Description/mx/dico/
+//   datatypes/_L8ZcEp0gEeOo48XfssNw8w
+const int kMaximumNumFractionalDigits = 10;
+
+// Max currency code length. Length of currency code can be at most 2048.
+const static size_t kMaxCurrencyCodeLength = 2048;
+
+// Returns whether the |currency_code| is valid to be used in ICU.
+bool ShouldUseCurrencyCode(const std::string& currency_code,
+                           const base::Optional<std::string> currency_system) {
+  return currency_system.value_or(kIso4217CurrencySystem) ==
+             kIso4217CurrencySystem &&
+         !currency_code.empty() &&
+         currency_code.size() <= kMaxCurrencyCodeLength;
+}
+
+}  // namespace
+
+CurrencyFormatter::CurrencyFormatter(
+    const std::string& currency_code,
+    const base::Optional<std::string> currency_system,
+    const std::string& locale_name)
+    : locale_(locale_name.c_str()) {
+  UErrorCode error_code = U_ZERO_ERROR;
+  icu_formatter_.reset(
+      icu::NumberFormat::createCurrencyInstance(locale_, error_code));
+  if (U_FAILURE(error_code)) {
+    icu::UnicodeString name;
+    std::string locale_str;
+    locale_.getDisplayName(name).toUTF8String(locale_str);
+    LOG(ERROR) << "Failed to initialize the currency formatter for "
+               << locale_str;
+    return;
+  }
+
+  if (ShouldUseCurrencyCode(currency_code, currency_system)) {
+    currency_code_.reset(new icu::UnicodeString(
+        currency_code.c_str(),
+        base::checked_cast<int32_t>(currency_code.size())));
+  } else {
+    // For non-ISO4217 currency system/code, we use a dummy code which is not
+    // going to appear in the output (stripped in Format()). This is because ICU
+    // NumberFormat will not accept an empty currency code. Under these
+    // circumstances, the number amount will be formatted according to locale,
+    // which is desirable (e.g. "55.00" -> "55,00" in fr_FR).
+    currency_code_.reset(new icu::UnicodeString("DUM", 3));
+  }
+
+  icu_formatter_->setCurrency(currency_code_->getBuffer(), error_code);
+  if (U_FAILURE(error_code)) {
+    std::string currency_code_str;
+    currency_code_->toUTF8String(currency_code_str);
+    LOG(ERROR) << "Could not set currency code on currency formatter: "
+               << currency_code_str;
+    return;
+  }
+
+  icu_formatter_->setMaximumFractionDigits(kMaximumNumFractionalDigits);
+}
+
+CurrencyFormatter::~CurrencyFormatter() {}
+
+base::string16 CurrencyFormatter::Format(const std::string& amount) {
+  // It's possible that the ICU formatter didn't initialize properly.
+  if (!icu_formatter_ || !icu_formatter_->getCurrency())
+    return base::UTF8ToUTF16(amount);
+
+  icu::UnicodeString output;
+  UErrorCode error_code = U_ZERO_ERROR;
+  icu_formatter_->format(icu::StringPiece(amount.c_str()), output, nullptr,
+                         error_code);
+
+  if (output.isEmpty())
+    return base::UTF8ToUTF16(amount);
+
+  // Explicitly removes the currency code (truncated to its 3-letter and
+  // 2-letter versions) from the output, because callers are expected to
+  // display the currency code alongside this result.
+  //
+  // 3+ letters: If currency code is "ABCDEF" or "BTX", this code will
+  // transform "ABC55.00"/"BTX55.00" to "55.00".
+  // 2 letters: If currency code is "CAD", this code will transform "CA$55.00"
+  // to "$55.00" (en_US) or "55,00 $ CA" to "55,00 $" (fr_FR).
+  icu::UnicodeString tmp_currency_code(*currency_code_);
+  tmp_currency_code.truncate(3);
+  output.findAndReplace(tmp_currency_code, "");
+  tmp_currency_code.truncate(2);
+  output.findAndReplace(tmp_currency_code, "");
+  // Trims any unicode whitespace (including non-breaking space).
+  if (u_isUWhiteSpace(output[0])) {
+    output.remove(0, 1);
+  }
+  if (u_isUWhiteSpace(output[output.length() - 1])) {
+    output.remove(output.length() - 1, 1);
+  }
+
+  std::string output_str;
+  output.toUTF8String(output_str);
+  return base::UTF8ToUTF16(output_str);
+}
+
+}  // namespace payments
diff --git a/components/payments/currency_formatter.h b/components/payments/currency_formatter.h
new file mode 100644
index 0000000..06695a84
--- /dev/null
+++ b/components/payments/currency_formatter.h
@@ -0,0 +1,54 @@
+// 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 COMPONENTS_PAYMENTS_CURRENCY_FORMATTER_H_
+#define COMPONENTS_PAYMENTS_CURRENCY_FORMATTER_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "base/optional.h"
+#include "base/strings/string16.h"
+#include "third_party/icu/source/common/unicode/locid.h"
+#include "third_party/icu/source/i18n/unicode/numfmt.h"
+
+namespace payments {
+
+// URI specifying the ISO4217 currency code specification. See for details:
+// https://w3c.github.io/browser-payment-api/#paymentcurrencyamount-dictionary
+extern const char kIso4217CurrencySystem[];
+
+// Currency formatter for amounts, according to a currency code, which typically
+// adheres to [ISO4217] (for example, "USD" for US Dollars).
+class CurrencyFormatter {
+ public:
+  // Initializes the CurrencyFormatter for a given |currency_code|,
+  // |currency_system| and |locale_name|. Note that |currency_code| and
+  // |currency_system| should have been validated (as part of
+  // payment_details_validation.h) before this is created.
+  CurrencyFormatter(const std::string& currency_code,
+                    const base::Optional<std::string> currency_system,
+                    const std::string& locale_name);
+  ~CurrencyFormatter();
+
+  // Formats the |amount| according to the currency code that was set. The
+  // result will NOT contain the currency code, nor a subset of it. Rather, the
+  // caller of this function should display the currency code separately. The
+  // return value may contain non-breaking space and is ready for display. In
+  // the case of a failure in initialization of the formatter or during
+  // formatter, this method will return |amount|.
+  base::string16 Format(const std::string& amount);
+
+ private:
+  const icu::Locale locale_;
+  std::unique_ptr<icu::UnicodeString> currency_code_;
+  std::unique_ptr<icu::NumberFormat> icu_formatter_;
+
+  DISALLOW_COPY_AND_ASSIGN(CurrencyFormatter);
+};
+
+}  // namespace payments
+
+#endif  // COMPONENTS_PAYMENTS_CURRENCY_FORMATTER_H_
diff --git a/components/payments/currency_formatter_unittest.cc b/components/payments/currency_formatter_unittest.cc
new file mode 100644
index 0000000..02e6cfb7
--- /dev/null
+++ b/components/payments/currency_formatter_unittest.cc
@@ -0,0 +1,132 @@
+// 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 "components/payments/currency_formatter.h"
+
+#include "base/optional.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace payments {
+
+struct TestCase {
+  TestCase(const char* amount,
+           const char* currency_code,
+           const char* locale_name,
+           const std::string& expected_amount,
+           const char* currency_system = kIso4217CurrencySystem)
+      : amount(amount),
+        currency_code(currency_code),
+        locale_name(locale_name),
+        expected_amount(expected_amount),
+        currency_system(currency_system) {}
+  ~TestCase() {}
+
+  const char* const amount;
+  const char* const currency_code;
+  const char* const locale_name;
+  const std::string expected_amount;
+  const base::Optional<std::string> currency_system;
+};
+
+class PaymentsCurrencyFormatterTest : public testing::TestWithParam<TestCase> {
+};
+
+TEST_P(PaymentsCurrencyFormatterTest, IsValidCurrencyFormat) {
+  CurrencyFormatter formatter(GetParam().currency_code,
+                              GetParam().currency_system,
+                              GetParam().locale_name);
+  base::string16 output_amount = formatter.Format(GetParam().amount);
+
+  // Convenience so the test cases can use regular spaces.
+  const base::string16 kSpace(base::ASCIIToUTF16(" "));
+  const base::string16 kNonBreakingSpace(base::UTF8ToUTF16("\xC2\xA0"));
+  base::string16 converted;
+  base::ReplaceChars(base::UTF8ToUTF16(GetParam().expected_amount), kSpace,
+                     kNonBreakingSpace, &converted);
+
+  EXPECT_EQ(converted, output_amount)
+      << "Failed to convert " << GetParam().amount << " ("
+      << GetParam().currency_code << ") in " << GetParam().locale_name;
+}
+
+INSTANTIATE_TEST_CASE_P(
+    CurrencyAmounts,
+    PaymentsCurrencyFormatterTest,
+    testing::Values(
+        TestCase("55.00", "USD", "en_US", "$55.00"),
+        TestCase("55.00", "USD", "en_CA", "$55.00"),
+        TestCase("55.00", "USD", "fr_CA", "55,00 $"),
+        TestCase("55.00", "USD", "fr_FR", "55,00 $"),
+        TestCase("1234", "USD", "fr_FR", "1 234,00 $"),
+
+        TestCase("55.5", "USD", "en_US", "$55.50"),
+        TestCase("55", "USD", "en_US", "$55.00"),
+        TestCase("123", "USD", "en_US", "$123.00"),
+        TestCase("1234", "USD", "en_US", "$1,234.00"),
+        TestCase("0.1234", "USD", "en_US", "$0.1234"),
+
+        TestCase("55.00", "EUR", "en_US", "€55.00"),
+        TestCase("55.00", "EUR", "fr_CA", "55,00 €"),
+        TestCase("55.00", "EUR", "fr_FR", "55,00 €"),
+
+        TestCase("55.00", "CAD", "en_US", "$55.00"),
+        TestCase("55.00", "CAD", "en_CA", "$55.00"),
+        TestCase("55.00", "CAD", "fr_CA", "55,00 $"),
+        TestCase("55.00", "CAD", "fr_FR", "55,00 $"),
+
+        TestCase("55.00", "BRL", "en_US", "R$55.00"),
+        TestCase("55.00", "BRL", "fr_CA", "55,00 R$"),
+        TestCase("55.00", "BRL", "pt_BR", "R$55,00"),
+
+        TestCase("55.00", "RUB", "en_US", "55.00"),
+        TestCase("55.00", "RUB", "fr_CA", "55,00"),
+        TestCase("55.00", "RUB", "ru_RU", "55,00 ₽"),
+
+        TestCase("55", "JPY", "ja_JP", "ï¿¥55"),
+        TestCase("55.0", "JPY", "ja_JP", "ï¿¥55"),
+        TestCase("55.00", "JPY", "ja_JP", "ï¿¥55"),
+        TestCase("55.12", "JPY", "ja_JP", "ï¿¥55.12"),
+        TestCase("55.49", "JPY", "ja_JP", "ï¿¥55.49"),
+        TestCase("55.50", "JPY", "ja_JP", "ï¿¥55.5"),
+        TestCase("55.9999", "JPY", "ja_JP", "ï¿¥55.9999"),
+
+        // Unofficial ISO 4217 currency code.
+        TestCase("55.00", "BTC", "en_US", "55.00"),
+        TestCase("-0.0000000001", "BTC", "en_US", "-0.0000000001"),
+        TestCase("-55.00", "BTC", "fr_FR", "-55,00"),
+
+        // Any string of at most 2048 characters can be a valid currency code.
+        TestCase("55.00", "", "en_US", "55.00"),
+        TestCase("55,00", "", "fr_CA", "55,00"),
+        TestCase("55,00", "", "fr-CA", "55,00"),
+        TestCase("55.00", "ABCDEF", "en_US", "55.00"),
+
+        // Edge cases.
+        TestCase("", "", "", ""),
+        TestCase("-1", "", "", "- 1.00"),
+        TestCase("-1.1255", "", "", "- 1.1255"),
+
+        // Handles big numbers.
+        TestCase(
+            "123456789012345678901234567890.123456789012345678901234567890",
+            "USD",
+            "fr_FR",
+            "123 456 789 012 345 678 901 234 567 890,123456789 $"),
+
+        // When the currency system is not ISO4217, only the amount is formatted
+        // using the locale (there is no other indication of currency).
+        TestCase("55.00", "USD", "en_CA", "55.00", "http://currsystem.com"),
+        TestCase("55.00", "USD", "fr_CA", "55,00", "http://currsystem.com"),
+        TestCase("55.00", "USD", "fr_FR", "55,00", "http://currsystem.com"),
+        TestCase("1234", "USD", "fr_FR", "1 234,00", "http://currsystem.com"),
+        TestCase("55.5", "USD", "en_US", "55.50", "http://currsystem.com"),
+        TestCase("55", "CAD", "en_US", "55.00", "http://currsystem.com"),
+        TestCase("123", "BTC", "en_US", "123.00", "http://currsystem.com"),
+        TestCase("1234", "JPY", "en_US", "1,234.00", "http://currsystem.com"),
+        TestCase("0.1234", "USD", "en_US", "0.1234", "http://currsystem.com")));
+
+}  // namespace payments
diff --git a/components/payments/payment_request.cc b/components/payments/payment_request.cc
index 98182c1..1a426c8 100644
--- a/components/payments/payment_request.cc
+++ b/components/payments/payment_request.cc
@@ -61,4 +61,16 @@
   manager_->DestroyRequest(this);
 }
 
+CurrencyFormatter* PaymentRequest::GetOrCreateCurrencyFormatter(
+    const std::string& currency_code,
+    const base::Optional<std::string> currency_system,
+    const std::string& locale_name) {
+  if (!currency_formatter_) {
+    currency_formatter_.reset(
+        new CurrencyFormatter(currency_code, currency_system, locale_name));
+  }
+
+  return currency_formatter_.get();
+}
+
 }  // namespace payments
diff --git a/components/payments/payment_request.h b/components/payments/payment_request.h
index cbd0e24..1a5f087d 100644
--- a/components/payments/payment_request.h
+++ b/components/payments/payment_request.h
@@ -7,6 +7,8 @@
 
 #include <memory>
 
+#include "base/optional.h"
+#include "components/payments/currency_formatter.h"
 #include "components/payments/payment_request.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
@@ -41,6 +43,16 @@
 
   void Cancel();
   void OnError();
+
+  // Returns the CurrencyFormatter instance for this PaymentRequest.
+  // |locale_name| should be the result of the browser's GetApplicationLocale().
+  // Note: Having multiple currencies per PaymentRequest is not supported; hence
+  // the CurrencyFormatter is cached here.
+  CurrencyFormatter* GetOrCreateCurrencyFormatter(
+      const std::string& currency_code,
+      const base::Optional<std::string> currency_system,
+      const std::string& locale_name);
+
   payments::mojom::PaymentDetails* details() { return details_.get(); }
 
   content::WebContents* web_contents() { return web_contents_; }
@@ -53,6 +65,7 @@
   mojo::Binding<payments::mojom::PaymentRequest> binding_;
   payments::mojom::PaymentRequestClientPtr client_;
   payments::mojom::PaymentDetailsPtr details_;
+  std::unique_ptr<CurrencyFormatter> currency_formatter_;
 
   DISALLOW_COPY_AND_ASSIGN(PaymentRequest);
 };
diff --git a/components/safe_browsing/base_resource_throttle.cc b/components/safe_browsing/base_resource_throttle.cc
index 902f64c..d30a0c4a7 100644
--- a/components/safe_browsing/base_resource_throttle.cc
+++ b/components/safe_browsing/base_resource_throttle.cc
@@ -328,21 +328,22 @@
       using subresource_filter::ContentSubresourceFilterDriverFactory;
       ContentSubresourceFilterDriverFactory* driver_factory =
           ContentSubresourceFilterDriverFactory::FromWebContents(web_contents);
-      DCHECK(driver_factory);
-
-      // For a redirect chain of A -> B -> C, the subresource filter expects C
-      // as the resource URL and [A, B] as redirect URLs.
-      std::vector<GURL> redirect_parent_urls;
-      if (!resource.redirect_urls.empty()) {
-        redirect_parent_urls.push_back(resource.original_url);
-        redirect_parent_urls.insert(redirect_parent_urls.end(),
-                                    resource.redirect_urls.begin(),
-                                    std::prev(resource.redirect_urls.end()));
+      // Content embedders (such as Android Webview) does not have a
+      // driver_factory.
+      if (driver_factory) {
+        // For a redirect chain of A -> B -> C, the subresource filter expects C
+        // as the resource URL and [A, B] as redirect URLs.
+        std::vector<GURL> redirect_parent_urls;
+        if (!resource.redirect_urls.empty()) {
+          redirect_parent_urls.push_back(resource.original_url);
+          redirect_parent_urls.insert(redirect_parent_urls.end(),
+                                      resource.redirect_urls.begin(),
+                                      std::prev(resource.redirect_urls.end()));
+        }
+        driver_factory->OnMainResourceMatchedSafeBrowsingBlacklist(
+            resource.url, redirect_parent_urls, resource.threat_type,
+            resource.threat_metadata.threat_pattern_type);
       }
-
-      driver_factory->OnMainResourceMatchedSafeBrowsingBlacklist(
-          resource.url, redirect_parent_urls, resource.threat_type,
-          resource.threat_metadata.threat_pattern_type);
     }
 
     ui_manager->DisplayBlockingPage(resource);
diff --git a/components/test_runner/test_runner_for_specific_view.cc b/components/test_runner/test_runner_for_specific_view.cc
index eb6cb792..026a715 100644
--- a/components/test_runner/test_runner_for_specific_view.cc
+++ b/components/test_runner/test_runner_for_specific_view.cc
@@ -601,7 +601,7 @@
   // This relies on the iframe focusing itself when it loads. This is a bit
   // sketchy, but it seems to be what other tests do.
   web_view()->focusedFrame()->executeScriptInIsolatedWorld(world_id, &source, 1,
-                                                           1, &values);
+                                                           &values);
   // Since only one script was added, only one result is expected
   if (values.size() == 1 && !values[0].IsEmpty())
     return values[0];
@@ -612,7 +612,7 @@
     int world_id,
     const std::string& script) {
   WebScriptSource source(WebString::fromUTF8(script));
-  web_view()->focusedFrame()->executeScriptInIsolatedWorld(world_id, &source, 1,
+  web_view()->focusedFrame()->executeScriptInIsolatedWorld(world_id, &source,
                                                            1);
 }
 
diff --git a/components/translate/content/renderer/translate_helper.cc b/components/translate/content/renderer/translate_helper.cc
index 51d5cac..dc572fa 100644
--- a/components/translate/content/renderer/translate_helper.cc
+++ b/components/translate/content/renderer/translate_helper.cc
@@ -109,11 +109,9 @@
 // TranslateHelper, public:
 TranslateHelper::TranslateHelper(content::RenderFrame* render_frame,
                                  int world_id,
-                                 int extension_group,
                                  const std::string& extension_scheme)
     : content::RenderFrameObserver(render_frame),
       world_id_(world_id),
-      extension_group_(extension_group),
       extension_scheme_(extension_scheme),
       binding_(this),
       weak_method_factory_(this) {}
@@ -238,8 +236,7 @@
     return;
 
   WebScriptSource source = WebScriptSource(ASCIIToUTF16(script));
-  main_frame->executeScriptInIsolatedWorld(
-      world_id_, &source, 1, extension_group_);
+  main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1);
 }
 
 bool TranslateHelper::ExecuteScriptAndGetBoolResult(const std::string& script,
@@ -251,8 +248,7 @@
   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
   WebVector<v8::Local<v8::Value> > results;
   WebScriptSource source = WebScriptSource(ASCIIToUTF16(script));
-  main_frame->executeScriptInIsolatedWorld(
-      world_id_, &source, 1, extension_group_, &results);
+  main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1, &results);
   if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsBoolean()) {
     NOTREACHED();
     return fallback;
@@ -270,8 +266,7 @@
   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
   WebVector<v8::Local<v8::Value> > results;
   WebScriptSource source = WebScriptSource(ASCIIToUTF16(script));
-  main_frame->executeScriptInIsolatedWorld(
-      world_id_, &source, 1, extension_group_, &results);
+  main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1, &results);
   if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsString()) {
     NOTREACHED();
     return std::string();
@@ -293,8 +288,7 @@
   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
   WebVector<v8::Local<v8::Value> > results;
   WebScriptSource source = WebScriptSource(ASCIIToUTF16(script));
-  main_frame->executeScriptInIsolatedWorld(
-      world_id_, &source, 1, extension_group_, &results);
+  main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1, &results);
   if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsNumber()) {
     NOTREACHED();
     return 0.0;
diff --git a/components/translate/content/renderer/translate_helper.h b/components/translate/content/renderer/translate_helper.h
index cdb3f2da..135d015b 100644
--- a/components/translate/content/renderer/translate_helper.h
+++ b/components/translate/content/renderer/translate_helper.h
@@ -31,7 +31,6 @@
  public:
   TranslateHelper(content::RenderFrame* render_frame,
                   int world_id,
-                  int extension_group,
                   const std::string& extension_scheme);
   ~TranslateHelper() override;
 
@@ -145,9 +144,6 @@
   // The world ID to use for script execution.
   int world_id_;
 
-  // The extension group.
-  int extension_group_;
-
   // The URL scheme for translate extensions.
   std::string extension_scheme_;
 
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 0b97376..51b4a372 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1091,8 +1091,8 @@
     "renderer_host/input/web_input_event_builders_mac.mm",
     "renderer_host/legacy_render_widget_host_win.cc",
     "renderer_host/legacy_render_widget_host_win.h",
-    "renderer_host/media/audio_input_debug_writer.cc",
-    "renderer_host/media/audio_input_debug_writer.h",
+    "renderer_host/media/audio_debug_file_writer.cc",
+    "renderer_host/media/audio_debug_file_writer.h",
     "renderer_host/media/audio_input_device_manager.cc",
     "renderer_host/media/audio_input_device_manager.h",
     "renderer_host/media/audio_input_renderer_host.cc",
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 11dfec2..895d389 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -59,7 +59,6 @@
     bool is_post) {
   switch (navigation_type) {
     case FrameMsg_Navigate_Type::RELOAD:
-    case FrameMsg_Navigate_Type::RELOAD_MAIN_RESOURCE:
     case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL:
       *load_flags |= net::LOAD_VALIDATE_CACHE;
       break;
@@ -147,7 +146,6 @@
 
   bool is_reload =
       navigation_type == FrameMsg_Navigate_Type::RELOAD ||
-      navigation_type == FrameMsg_Navigate_Type::RELOAD_MAIN_RESOURCE ||
       navigation_type == FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE ||
       navigation_type == FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
   if (is_reload)
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 076828a..09d7ed9 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -58,7 +58,7 @@
     ReloadType reload_type) {
   switch (reload_type) {
     case ReloadType::NORMAL:
-      return FrameMsg_Navigate_Type::RELOAD_MAIN_RESOURCE;
+      return FrameMsg_Navigate_Type::RELOAD;
     case ReloadType::BYPASSING_CACHE:
     case ReloadType::DISABLE_LOFI_MODE:
       return FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE;
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc
index 057f70f..b828ab1 100644
--- a/content/browser/frame_host/navigator_impl_unittest.cc
+++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -834,7 +834,7 @@
   // A NavigationRequest should have been generated.
   NavigationRequest* main_request = node->navigation_request();
   ASSERT_TRUE(main_request != NULL);
-  EXPECT_EQ(FrameMsg_Navigate_Type::RELOAD_MAIN_RESOURCE,
+  EXPECT_EQ(FrameMsg_Navigate_Type::RELOAD,
             main_request->common_params().navigation_type);
   main_test_rfh()->PrepareForCommit();
   EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
diff --git a/content/browser/renderer_host/media/audio_input_debug_writer.cc b/content/browser/renderer_host/media/audio_debug_file_writer.cc
similarity index 91%
rename from content/browser/renderer_host/media/audio_input_debug_writer.cc
rename to content/browser/renderer_host/media/audio_debug_file_writer.cc
index 9ffb94f0..1656a1cc 100644
--- a/content/browser/renderer_host/media/audio_input_debug_writer.cc
+++ b/content/browser/renderer_host/media/audio_debug_file_writer.cc
@@ -2,10 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/browser/renderer_host/media/audio_input_debug_writer.h"
+#include "content/browser/renderer_host/media/audio_debug_file_writer.h"
+
 #include <stdint.h>
 #include <array>
 #include <utility>
+
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/sys_byteorder.h"
@@ -131,7 +133,7 @@
 // Manages the debug recording file and writes to it. Can be created on any
 // thread. All the operations must be executed on FILE thread. Must be destroyed
 // on FILE thread.
-class AudioInputDebugWriter::AudioFileWriter {
+class AudioDebugFileWriter::AudioFileWriter {
  public:
   static AudioFileWriterUniquePtr Create(const base::FilePath& file_name,
                                          const media::AudioParameters& params);
@@ -167,8 +169,8 @@
 };
 
 // static
-AudioInputDebugWriter::AudioFileWriterUniquePtr
-AudioInputDebugWriter::AudioFileWriter::Create(
+AudioDebugFileWriter::AudioFileWriterUniquePtr
+AudioDebugFileWriter::AudioFileWriter::Create(
     const base::FilePath& file_name,
     const media::AudioParameters& params) {
   AudioFileWriterUniquePtr file_writer(new AudioFileWriter(params));
@@ -182,19 +184,19 @@
   return file_writer;
 }
 
-AudioInputDebugWriter::AudioFileWriter::AudioFileWriter(
+AudioDebugFileWriter::AudioFileWriter::AudioFileWriter(
     const media::AudioParameters& params)
     : samples_(0), params_(params), interleaved_data_size_(0) {
   DCHECK_EQ(params.bits_per_sample(), kBytesPerSample * 8);
 }
 
-AudioInputDebugWriter::AudioFileWriter::~AudioFileWriter() {
+AudioDebugFileWriter::AudioFileWriter::~AudioFileWriter() {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
   if (file_.IsValid())
     WriteHeader();
 }
 
-void AudioInputDebugWriter::AudioFileWriter::Write(
+void AudioDebugFileWriter::AudioFileWriter::Write(
     const media::AudioBus* data) {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
   if (!file_.IsValid())
@@ -221,7 +223,7 @@
                           data_size * sizeof(interleaved_data_[0]));
 }
 
-void AudioInputDebugWriter::AudioFileWriter::WriteHeader() {
+void AudioDebugFileWriter::AudioFileWriter::WriteHeader() {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
   if (!file_.IsValid())
     return;
@@ -234,7 +236,7 @@
   file_.Seek(base::File::FROM_BEGIN, kWavHeaderSize);
 }
 
-void AudioInputDebugWriter::AudioFileWriter::CreateRecordingFile(
+void AudioDebugFileWriter::AudioFileWriter::CreateRecordingFile(
     const base::FilePath& file_name) {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
   DCHECK(!file_.IsValid());
@@ -247,7 +249,7 @@
     return;
   }
 
-  // Note that we do not inform AudioInputDebugWriter that the file creation
+  // Note that we do not inform AudioDebugFileWriter that the file creation
   // fails, so it will continue to post data to be recorded, which won't
   // be written to the file. This also won't be reflected in WillWrite(). It's
   // fine, because this situation is rare, and all the posting is expected to
@@ -258,30 +260,30 @@
               << file_.error_details();
 }
 
-AudioInputDebugWriter::AudioInputDebugWriter(
+AudioDebugFileWriter::AudioDebugFileWriter(
     const media::AudioParameters& params)
     : params_(params) {
   client_sequence_checker_.DetachFromSequence();
 }
 
-AudioInputDebugWriter::~AudioInputDebugWriter() {
+AudioDebugFileWriter::~AudioDebugFileWriter() {
   // |file_writer_| will be deleted on FILE thread.
 }
 
-void AudioInputDebugWriter::Start(const base::FilePath& file_name) {
+void AudioDebugFileWriter::Start(const base::FilePath& file_name) {
   DCHECK(client_sequence_checker_.CalledOnValidSequence());
   DCHECK(!file_writer_);
   file_writer_ = AudioFileWriter::Create(file_name, params_);
 }
 
-void AudioInputDebugWriter::Stop() {
+void AudioDebugFileWriter::Stop() {
   DCHECK(client_sequence_checker_.CalledOnValidSequence());
   // |file_writer_| is deleted on FILE thread.
   file_writer_.reset();
   client_sequence_checker_.DetachFromSequence();
 }
 
-void AudioInputDebugWriter::Write(std::unique_ptr<media::AudioBus> data) {
+void AudioDebugFileWriter::Write(std::unique_ptr<media::AudioBus> data) {
   DCHECK(client_sequence_checker_.CalledOnValidSequence());
   if (!file_writer_)
     return;
@@ -294,7 +296,7 @@
                  base::Owned(data.release())));
 }
 
-bool AudioInputDebugWriter::WillWrite() {
+bool AudioDebugFileWriter::WillWrite() {
   // Note that if this is called from any place other than
   // |client_sequence_checker_| then there is a data race here, but it's fine,
   // because Write() will check for |file_writer_|. So, we are not very precise
diff --git a/content/browser/renderer_host/media/audio_input_debug_writer.h b/content/browser/renderer_host/media/audio_debug_file_writer.h
similarity index 69%
rename from content/browser/renderer_host/media/audio_input_debug_writer.h
rename to content/browser/renderer_host/media/audio_debug_file_writer.h
index c618667..1ef10f1 100644
--- a/content/browser/renderer_host/media/audio_input_debug_writer.h
+++ b/content/browser/renderer_host/media/audio_debug_file_writer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_DEBUG_WRITER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_DEBUG_WRITER_H_
+#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_DEBUG_FILE_WRITER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_DEBUG_FILE_WRITER_H_
 
 #include <stdint.h>
 
@@ -14,7 +14,7 @@
 #include "base/sequence_checker.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/browser_thread.h"
-#include "media/audio/audio_input_writer.h"
+#include "media/audio/audio_file_writer.h"
 #include "media/base/audio_parameters.h"
 
 namespace media {
@@ -27,11 +27,11 @@
 
 // Writes audio input data used for debugging purposes. All operations are
 // non-blocking.
-class CONTENT_EXPORT AudioInputDebugWriter
-    : public NON_EXPORTED_BASE(media::AudioInputWriter) {
+class CONTENT_EXPORT AudioDebugFileWriter
+    : public NON_EXPORTED_BASE(media::AudioFileWriter) {
  public:
-  explicit AudioInputDebugWriter(const media::AudioParameters& params);
-  ~AudioInputDebugWriter() override;
+  explicit AudioDebugFileWriter(const media::AudioParameters& params);
+  ~AudioDebugFileWriter() override;
 
   void Start(const base::FilePath& file) override;
   void Stop() override;
@@ -49,4 +49,4 @@
 
 }  // namspace content
 
-#endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_DEBUG_WRITER_H_
+#endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_DEBUG_FILE_WRITER_H_
diff --git a/content/browser/renderer_host/media/audio_input_debug_writer_unittest.cc b/content/browser/renderer_host/media/audio_debug_file_writer_unittest.cc
similarity index 88%
rename from content/browser/renderer_host/media/audio_input_debug_writer_unittest.cc
rename to content/browser/renderer_host/media/audio_debug_file_writer_unittest.cc
index 643fc33..4ececd0 100644
--- a/content/browser/renderer_host/media/audio_input_debug_writer_unittest.cc
+++ b/content/browser/renderer_host/media/audio_debug_file_writer_unittest.cc
@@ -8,7 +8,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/sys_byteorder.h"
-#include "content/browser/renderer_host/media/audio_input_debug_writer.h"
+#include "content/browser/renderer_host/media/audio_debug_file_writer.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "media/base/audio_bus.h"
@@ -37,12 +37,12 @@
 
 // <channel layout, sample rate, frames per buffer, number of buffer writes
 typedef std::tr1::tuple<media::ChannelLayout, int, int, int>
-    AudioInputDebugWriterTestData;
+    AudioDebugFileWriterTestData;
 
-class AudioInputDebugWriterTest
-    : public testing::TestWithParam<AudioInputDebugWriterTestData> {
+class AudioDebugFileWriterTest
+    : public testing::TestWithParam<AudioDebugFileWriterTestData> {
  public:
-  AudioInputDebugWriterTest()
+  AudioDebugFileWriterTest()
       : thread_bundle_(content::TestBrowserThreadBundle::REAL_FILE_THREAD),
         params_(media::AudioParameters::Format::AUDIO_PCM_LINEAR,
                 std::tr1::get<0>(GetParam()),
@@ -58,7 +58,7 @@
   }
 
  protected:
-  virtual ~AudioInputDebugWriterTest() {}
+  virtual ~AudioDebugFileWriterTest() {}
 
   static void InitSourceInterleaved(int16_t* source_interleaved,
                                     int source_samples) {
@@ -181,7 +181,7 @@
     // done.
     BrowserThread::PostTask(
         BrowserThread::FILE, FROM_HERE,
-        base::Bind(&AudioInputDebugWriterTest::TestDoneOnFileThread,
+        base::Bind(&AudioDebugFileWriterTest::TestDoneOnFileThread,
                    base::Unretained(this), event.GetClosure()));
 
     // Wait for TestDoneOnFileThread() to call event's closure.
@@ -214,7 +214,7 @@
   TestBrowserThreadBundle thread_bundle_;
 
   // Writer under test.
-  std::unique_ptr<AudioInputDebugWriter> input_debug_writer_;
+  std::unique_ptr<AudioDebugFileWriter> input_debug_writer_;
 
   // AudioBus parameters.
   media::AudioParameters params_;
@@ -229,20 +229,20 @@
   std::unique_ptr<int16_t[]> source_interleaved_;
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(AudioInputDebugWriterTest);
+  DISALLOW_COPY_AND_ASSIGN(AudioDebugFileWriterTest);
 };
 
-class AudioInputDebugWriterBehavioralTest : public AudioInputDebugWriterTest {};
+class AudioDebugFileWriterBehavioralTest : public AudioDebugFileWriterTest {};
 
-TEST_P(AudioInputDebugWriterTest, WaveRecordingTest) {
-  input_debug_writer_.reset(new AudioInputDebugWriter(params_));
+TEST_P(AudioDebugFileWriterTest, WaveRecordingTest) {
+  input_debug_writer_.reset(new AudioDebugFileWriter(params_));
 
   RecordAndVerifyOnce();
 }
 
-TEST_P(AudioInputDebugWriterBehavioralTest,
+TEST_P(AudioDebugFileWriterBehavioralTest,
        DeletedBeforeRecordingFinishedOnFileThread) {
-  input_debug_writer_.reset(new AudioInputDebugWriter(params_));
+  input_debug_writer_.reset(new AudioDebugFileWriter(params_));
 
   base::FilePath file_path;
   EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
@@ -274,26 +274,26 @@
   }
 }
 
-TEST_P(AudioInputDebugWriterBehavioralTest, FileCreationError) {
-  input_debug_writer_.reset(new AudioInputDebugWriter(params_));
+TEST_P(AudioDebugFileWriterBehavioralTest, FileCreationError) {
+  input_debug_writer_.reset(new AudioDebugFileWriter(params_));
   base::FilePath file_path;  // Empty file name.
   input_debug_writer_->Start(file_path);
   DoDebugRecording();
 }
 
-TEST_P(AudioInputDebugWriterBehavioralTest, StartStopStartStop) {
-  input_debug_writer_.reset(new AudioInputDebugWriter(params_));
+TEST_P(AudioDebugFileWriterBehavioralTest, StartStopStartStop) {
+  input_debug_writer_.reset(new AudioDebugFileWriter(params_));
   RecordAndVerifyOnce();
   RecordAndVerifyOnce();
 }
 
-TEST_P(AudioInputDebugWriterBehavioralTest, DestroyNotStarted) {
-  input_debug_writer_.reset(new AudioInputDebugWriter(params_));
+TEST_P(AudioDebugFileWriterBehavioralTest, DestroyNotStarted) {
+  input_debug_writer_.reset(new AudioDebugFileWriter(params_));
   input_debug_writer_.reset();
 }
 
-TEST_P(AudioInputDebugWriterBehavioralTest, DestroyStarted) {
-  input_debug_writer_.reset(new AudioInputDebugWriter(params_));
+TEST_P(AudioDebugFileWriterBehavioralTest, DestroyStarted) {
+  input_debug_writer_.reset(new AudioDebugFileWriter(params_));
   base::FilePath file_path;
   EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
   input_debug_writer_->Start(file_path);
@@ -301,8 +301,8 @@
 }
 
 INSTANTIATE_TEST_CASE_P(
-    AudioInputDebugWriterTest,
-    AudioInputDebugWriterTest,
+    AudioDebugFileWriterTest,
+    AudioDebugFileWriterTest,
     // Using 10ms frames per buffer everywhere.
     testing::Values(
         // No writes.
@@ -337,8 +337,8 @@
                              1500)));
 
 INSTANTIATE_TEST_CASE_P(
-    AudioInputDebugWriterBehavioralTest,
-    AudioInputDebugWriterBehavioralTest,
+    AudioDebugFileWriterBehavioralTest,
+    AudioDebugFileWriterBehavioralTest,
     // Using 10ms frames per buffer everywhere.
     testing::Values(
         // No writes.
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.cc b/content/browser/renderer_host/media/audio_input_renderer_host.cc
index 444761c..d0c9b32 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -22,7 +22,7 @@
 #include "content/browser/media/capture/desktop_capture_device_uma_types.h"
 #include "content/browser/media/capture/web_contents_audio_input_stream.h"
 #include "content/browser/media/media_internals.h"
-#include "content/browser/renderer_host/media/audio_input_debug_writer.h"
+#include "content/browser/renderer_host/media/audio_debug_file_writer.h"
 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
 #include "content/browser/renderer_host/media/audio_input_sync_writer.h"
 #include "content/browser/renderer_host/media/media_stream_manager.h"
@@ -348,10 +348,10 @@
   }
 
 #if BUILDFLAG(ENABLE_WEBRTC)
-  std::unique_ptr<media::AudioInputWriter> debug_writer(
-      new AudioInputDebugWriter(audio_params));
+  std::unique_ptr<media::AudioFileWriter> debug_writer(
+      new AudioDebugFileWriter(audio_params));
 #else
-  std::unique_ptr<media::AudioInputWriter> debug_writer(nullptr);
+  std::unique_ptr<media::AudioFileWriter> debug_writer(nullptr);
 #endif
 
   // If we have successfully created the SyncWriter then assign it to the
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
index 55a3af35..3a62616 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
@@ -24,7 +24,7 @@
 #include "content/public/test/test_browser_thread.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "media/audio/audio_device_description.h"
-#include "media/audio/audio_input_writer.h"
+#include "media/audio/audio_file_writer.h"
 #include "media/audio/fake_audio_log_factory.h"
 #include "media/audio/fake_audio_manager.h"
 #include "media/base/media_switches.h"
diff --git a/content/common/frame_message_enums.h b/content/common/frame_message_enums.h
index 8913847..3d9f84a 100644
--- a/content/common/frame_message_enums.h
+++ b/content/common/frame_message_enums.h
@@ -10,13 +10,8 @@
 struct FrameMsg_Navigate_Type {
  public:
   enum Value {
-    // Reload the page, validating cache entries.
-    RELOAD,
-
     // Reload the page, validating only cache entry for the main resource.
-    // TODO(toyoshim): We should rename this one to be RELOAD and remove the old
-    // unused RELOAD behavior.
-    RELOAD_MAIN_RESOURCE,
+    RELOAD,
 
     // Reload the page, bypassing any cache entries.
     RELOAD_BYPASSING_CACHE,
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json
index e31bd29..147245b1 100644
--- a/content/public/app/mojo/content_browser_manifest.json
+++ b/content/public/app/mojo/content_browser_manifest.json
@@ -30,7 +30,6 @@
           "device::mojom::MotionSensor",
           "device::mojom::OrientationAbsoluteSensor",
           "device::mojom::OrientationSensor",
-          "device::mojom::TimeZoneMonitor",
           "discardable_memory::mojom::DiscardableSharedMemoryManager",
           "media::mojom::ImageCapture",
           "memory_coordinator::mojom::MemoryCoordinatorHandle",
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index 4734a06..0c8dfed 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -67,7 +67,6 @@
   virtual void DidFinishLoad() {}
   virtual void DidFinishDocumentLoad() {}
   virtual void DidCreateScriptContext(v8::Local<v8::Context> context,
-                                      int extension_group,
                                       int world_id) {}
   virtual void WillReleaseScriptContext(v8::Local<v8::Context> context,
                                         int world_id) {}
diff --git a/content/renderer/DEPS b/content/renderer/DEPS
index 98c4ec9..ba500b9 100644
--- a/content/renderer/DEPS
+++ b/content/renderer/DEPS
@@ -15,7 +15,6 @@
   "+device/gamepad/public/interfaces",
   "+device/screen_orientation/public/interfaces",
   "+device/sensors/public",
-  "+device/time_zone_monitor/public",
   "+device/usb/public",
   "+device/vibration",
   "+gin",
diff --git a/content/renderer/dom_automation_controller.cc b/content/renderer/dom_automation_controller.cc
index 7518914..b8253de1 100644
--- a/content/renderer/dom_automation_controller.cc
+++ b/content/renderer/dom_automation_controller.cc
@@ -60,7 +60,6 @@
 
 void DomAutomationController::DidCreateScriptContext(
     v8::Local<v8::Context> context,
-    int extension_group,
     int world_id) {
   // Add the domAutomationController to isolated worlds as well.
   v8::Isolate* isolate = blink::mainThreadIsolate();
diff --git a/content/renderer/dom_automation_controller.h b/content/renderer/dom_automation_controller.h
index ac09e4a..d684f96 100644
--- a/content/renderer/dom_automation_controller.h
+++ b/content/renderer/dom_automation_controller.h
@@ -118,7 +118,6 @@
   // RenderFrameObserver
   void OnDestruct() override;
   void DidCreateScriptContext(v8::Local<v8::Context> context,
-                              int extension_group,
                               int world_id) override;
 
   int automation_id_;  // routing id to be used by the next channel.
diff --git a/content/renderer/mus/BUILD.gn b/content/renderer/mus/BUILD.gn
index 8ac01edb..d59981d 100644
--- a/content/renderer/mus/BUILD.gn
+++ b/content/renderer/mus/BUILD.gn
@@ -23,7 +23,6 @@
     "//content/common",
     "//content/public/child:child_sources",
     "//content/public/common:common_sources",
-    "//device/time_zone_monitor/public/interfaces",
     "//media/mojo/interfaces:remoting",
     "//mojo/common",
     "//services/service_manager/public/cpp",
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 04516c35..c0adcb2 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -656,7 +656,6 @@
 bool IsReload(FrameMsg_Navigate_Type::Value navigation_type) {
   switch (navigation_type) {
     case FrameMsg_Navigate_Type::RELOAD:
-    case FrameMsg_Navigate_Type::RELOAD_MAIN_RESOURCE:
     case FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE:
     case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL:
       return true;
@@ -674,8 +673,6 @@
   switch (navigation_type) {
     case FrameMsg_Navigate_Type::RELOAD:
     case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL:
-      return WebFrameLoadType::Reload;
-    case FrameMsg_Navigate_Type::RELOAD_MAIN_RESOURCE:
       return WebFrameLoadType::ReloadMainResource;
     case FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE:
       return WebFrameLoadType::ReloadBypassingCache;
@@ -2002,7 +1999,7 @@
   WebScriptSource script = WebScriptSource(jscript);
   JavaScriptIsolatedWorldRequest* request = new JavaScriptIsolatedWorldRequest(
       id, notify_result, routing_id_, weak_factory_.GetWeakPtr());
-  frame_->requestExecuteScriptInIsolatedWorld(world_id, &script, 1, 0, false,
+  frame_->requestExecuteScriptInIsolatedWorld(world_id, &script, 1, false,
                                               request);
 }
 
@@ -4497,12 +4494,11 @@
 
 void RenderFrameImpl::didCreateScriptContext(blink::WebLocalFrame* frame,
                                              v8::Local<v8::Context> context,
-                                             int extension_group,
                                              int world_id) {
   DCHECK_EQ(frame_, frame);
 
   for (auto& observer : observers_)
-    observer.DidCreateScriptContext(context, extension_group, world_id);
+    observer.DidCreateScriptContext(context, world_id);
 }
 
 void RenderFrameImpl::willReleaseScriptContext(blink::WebLocalFrame* frame,
@@ -6357,6 +6353,7 @@
     const GURL base_url = params.base_url_for_data_url.is_empty() ?
         params.url : params.base_url_for_data_url;
     bool replace = load_type == WebFrameLoadType::ReloadBypassingCache ||
+                   load_type == WebFrameLoadType::ReloadMainResource ||
                    load_type == WebFrameLoadType::Reload;
 
     frame->loadData(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 03aa45a6..f415989 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -607,7 +607,6 @@
       blink::WebLoadingBehaviorFlag behavior) override;
   void didCreateScriptContext(blink::WebLocalFrame* frame,
                               v8::Local<v8::Context> context,
-                              int extension_group,
                               int world_id) override;
   void willReleaseScriptContext(blink::WebLocalFrame* frame,
                                 v8::Local<v8::Context> context,
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index 7186122..af65af0 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -2557,7 +2557,7 @@
   LoadHTML("<body>page</body>");
   blink::WebScriptSource source1(
       WebString::fromUTF8("function func1() { debugger; }"));
-  frame()->GetWebFrame()->executeScriptInIsolatedWorld(17, &source1, 1, 1);
+  frame()->GetWebFrame()->executeScriptInIsolatedWorld(17, &source1, 1);
 
   Attach();
   DispatchDevToolsMessage("Debugger.enable",
@@ -2566,7 +2566,7 @@
   ExpectPauseAndResume(3);
   blink::WebScriptSource source2(
       WebString::fromUTF8("function func2() { func1(); }; func2();"));
-  frame()->GetWebFrame()->executeScriptInIsolatedWorld(17, &source2, 1, 1);
+  frame()->GetWebFrame()->executeScriptInIsolatedWorld(17, &source2, 1);
 
   EXPECT_FALSE(IsPaused());
   Detach();
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index fcf7c2f..4a6a2b6 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1194,7 +1194,7 @@
     "../browser/renderer_host/input/web_input_event_builders_android_unittest.cc",
     "../browser/renderer_host/input/web_input_event_builders_mac_unittest.mm",
     "../browser/renderer_host/input/web_input_event_util_unittest.cc",
-    "../browser/renderer_host/media/audio_input_debug_writer_unittest.cc",
+    "../browser/renderer_host/media/audio_debug_file_writer_unittest.cc",
     "../browser/renderer_host/media/audio_input_device_manager_unittest.cc",
     "../browser/renderer_host/media/audio_input_renderer_host_unittest.cc",
     "../browser/renderer_host/media/audio_input_sync_writer_unittest.cc",
diff --git a/extensions/common/api/_behavior_features.json b/extensions/common/api/_behavior_features.json
index e64975f..1f39caf2 100644
--- a/extensions/common/api/_behavior_features.json
+++ b/extensions/common/api/_behavior_features.json
@@ -43,7 +43,7 @@
     ]
   },
   "allow_usb_devices_permission_interface_class": {
-    "channel": "dev",
+    "channel": "stable",
     "extension_types": ["platform_app"],
     "session_types": ["kiosk"] 
   },
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn
index 8579e36..3224ccf 100644
--- a/extensions/renderer/BUILD.gn
+++ b/extensions/renderer/BUILD.gn
@@ -66,7 +66,6 @@
     "extension_bindings_system.h",
     "extension_frame_helper.cc",
     "extension_frame_helper.h",
-    "extension_groups.h",
     "extension_helper.cc",
     "extension_helper.h",
     "extension_injection_host.cc",
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index a1b2b51e..b646bab 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -316,12 +316,11 @@
 void Dispatcher::DidCreateScriptContext(
     blink::WebLocalFrame* frame,
     const v8::Local<v8::Context>& v8_context,
-    int extension_group,
     int world_id) {
   const base::TimeTicks start_time = base::TimeTicks::Now();
 
-  ScriptContext* context = script_context_set_->Register(
-      frame, v8_context, extension_group, world_id);
+  ScriptContext* context =
+      script_context_set_->Register(frame, v8_context, world_id);
 
   // Initialize origin permissions for content scripts, which can't be
   // initialized in |OnActivateExtension|.
diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h
index 7f1910c..677b40e 100644
--- a/extensions/renderer/dispatcher.h
+++ b/extensions/renderer/dispatcher.h
@@ -87,7 +87,6 @@
 
   void DidCreateScriptContext(blink::WebLocalFrame* frame,
                               const v8::Local<v8::Context>& context,
-                              int extension_group,
                               int world_id);
 
   // Runs on a different thread and should only use thread safe member
diff --git a/extensions/renderer/extension_frame_helper.cc b/extensions/renderer/extension_frame_helper.cc
index 5d3709e4..91d38c3 100644
--- a/extensions/renderer/extension_frame_helper.cc
+++ b/extensions/renderer/extension_frame_helper.cc
@@ -198,18 +198,16 @@
   v8::Local<v8::Context> context =
       render_frame()->GetWebFrame()->mainWorldScriptContext();
   v8::Context::Scope context_scope(context);
-  extension_dispatcher_->DidCreateScriptContext(
-      render_frame()->GetWebFrame(), context, 0, 0);
+  extension_dispatcher_->DidCreateScriptContext(render_frame()->GetWebFrame(),
+                                                context, 0);
   // TODO(devlin): Add constants for main world id, no extension group.
 }
 
 void ExtensionFrameHelper::DidCreateScriptContext(
     v8::Local<v8::Context> context,
-    int extension_group,
     int world_id) {
   if (context == render_frame()->GetWebFrame()->mainWorldScriptContext() &&
       render_frame()->IsBrowserSideNavigationPending()) {
-    DCHECK_EQ(0, extension_group);
     DCHECK_EQ(0, world_id);
     DCHECK(!delayed_main_world_script_initialization_);
     // Defer initializing the extensions script context now because it depends
@@ -217,8 +215,8 @@
     // point with PlzNavigate.
     delayed_main_world_script_initialization_ = true;
   } else {
-    extension_dispatcher_->DidCreateScriptContext(
-        render_frame()->GetWebFrame(), context, extension_group, world_id);
+    extension_dispatcher_->DidCreateScriptContext(render_frame()->GetWebFrame(),
+                                                  context, world_id);
   }
 }
 
diff --git a/extensions/renderer/extension_frame_helper.h b/extensions/renderer/extension_frame_helper.h
index d55f624f..f45129e 100644
--- a/extensions/renderer/extension_frame_helper.h
+++ b/extensions/renderer/extension_frame_helper.h
@@ -92,7 +92,6 @@
           override;
   void DidStartProvisionalLoad() override;
   void DidCreateScriptContext(v8::Local<v8::Context>,
-                              int extension_group,
                               int world_id) override;
   void WillReleaseScriptContext(v8::Local<v8::Context>, int world_id) override;
   bool OnMessageReceived(const IPC::Message& message) override;
diff --git a/extensions/renderer/extension_groups.h b/extensions/renderer/extension_groups.h
deleted file mode 100644
index 9766fa4e..0000000
--- a/extensions/renderer/extension_groups.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef EXTENSIONS_RENDERER_EXTENSION_GROUPS_H_
-#define EXTENSIONS_RENDERER_EXTENSION_GROUPS_H_
-
-namespace extensions {
-
-// A set of extension groups for use with blink::registerExtension and
-// WebFrame::ExecuteScriptInNewWorld to control which extensions get loaded
-// into which contexts.
-// TODO(kalman): Remove this when https://crbug.com/481699 is fixed.
-enum ExtensionGroups {
-  // Use this to mark extensions to be loaded into content scripts only.
-  EXTENSION_GROUP_CONTENT_SCRIPTS = 1,
-};
-
-}  // namespace extensions
-
-#endif  // EXTENSIONS_RENDERER_EXTENSION_GROUPS_H_
diff --git a/extensions/renderer/gc_callback_unittest.cc b/extensions/renderer/gc_callback_unittest.cc
index 36f96604..e6dfab6 100644
--- a/extensions/renderer/gc_callback_unittest.cc
+++ b/extensions/renderer/gc_callback_unittest.cc
@@ -14,6 +14,7 @@
 #include "extensions/renderer/scoped_web_frame.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/script_context_set.h"
+#include "extensions/renderer/test_extensions_renderer_client.h"
 #include "gin/function_template.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
@@ -42,11 +43,10 @@
   }
 
   ScriptContext* RegisterScriptContext() {
-    // No extension group or world ID.
+    // No world ID.
     return script_context_set_.Register(
         web_frame_.frame(),
-        v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), v8_context_), 0,
-        0);
+        v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), v8_context_), 0);
   }
 
   void RequestGarbageCollection() {
@@ -73,6 +73,8 @@
 
   base::MessageLoop message_loop_;
   ScopedWebFrame web_frame_;  // (this will construct the v8::Isolate)
+  // ExtensionsRendererClient is a dependency of ScriptContextSet.
+  TestExtensionsRendererClient extensions_renderer_client_;
   ExtensionIdSet active_extensions_;
   ScriptContextSet script_context_set_;
   v8::Global<v8::Context> v8_context_;
diff --git a/extensions/renderer/script_context_set.cc b/extensions/renderer/script_context_set.cc
index 8f60dc9..0f813a05 100644
--- a/extensions/renderer/script_context_set.cc
+++ b/extensions/renderer/script_context_set.cc
@@ -10,7 +10,7 @@
 #include "content/public/common/url_constants.h"
 #include "content/public/renderer/render_frame.h"
 #include "extensions/common/extension.h"
-#include "extensions/renderer/extension_groups.h"
+#include "extensions/renderer/extensions_renderer_client.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/script_injection.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
@@ -37,7 +37,6 @@
 ScriptContext* ScriptContextSet::Register(
     blink::WebLocalFrame* frame,
     const v8::Local<v8::Context>& v8_context,
-    int extension_group,
     int world_id) {
   const Extension* extension =
       GetExtensionFromFrameAndWorld(frame, world_id, false);
@@ -45,11 +44,10 @@
       GetExtensionFromFrameAndWorld(frame, world_id, true);
 
   GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame);
-  Feature::Context context_type =
-      ClassifyJavaScriptContext(extension, extension_group, frame_url,
-                                frame->document().getSecurityOrigin());
+  Feature::Context context_type = ClassifyJavaScriptContext(
+      extension, world_id, frame_url, frame->document().getSecurityOrigin());
   Feature::Context effective_context_type = ClassifyJavaScriptContext(
-      effective_extension, extension_group,
+      effective_extension, world_id,
       ScriptContext::GetEffectiveDocumentURL(frame, frame_url, true),
       frame->document().getSecurityOrigin());
 
@@ -171,14 +169,17 @@
 
 Feature::Context ScriptContextSet::ClassifyJavaScriptContext(
     const Extension* extension,
-    int extension_group,
+    int world_id,
     const GURL& url,
     const blink::WebSecurityOrigin& origin) {
   // WARNING: This logic must match ProcessMap::GetContextType, as much as
   // possible.
 
-  DCHECK_GE(extension_group, 0);
-  if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) {
+  // Worlds not within this range are not for content scripts, so ignore them.
+  // TODO(devlin): Isolated worlds with a non-zero id could belong to
+  // chrome-internal pieces, like dom distiller and translate. Do we need any
+  // bindings (even those for basic web pages) for those?
+  if (world_id >= ExtensionsRendererClient::Get()->GetLowestIsolatedWorldId()) {
     return extension ?  // TODO(kalman): when does this happen?
                Feature::CONTENT_SCRIPT_CONTEXT
                      : Feature::UNSPECIFIED_CONTEXT;
diff --git a/extensions/renderer/script_context_set.h b/extensions/renderer/script_context_set.h
index 8cf1671..9f47d0a 100644
--- a/extensions/renderer/script_context_set.h
+++ b/extensions/renderer/script_context_set.h
@@ -55,7 +55,6 @@
   // Returns a weak reference to the new ScriptContext.
   ScriptContext* Register(blink::WebLocalFrame* frame,
                           const v8::Local<v8::Context>& v8_context,
-                          int extension_group,
                           int world_id);
 
   // If the specified context is contained in this set, remove it, then delete
@@ -121,7 +120,7 @@
   // Returns the Feature::Context type of context for a JavaScript context.
   Feature::Context ClassifyJavaScriptContext(
       const Extension* extension,
-      int extension_group,
+      int world_id,
       const GURL& url,
       const blink::WebSecurityOrigin& origin);
 
diff --git a/extensions/renderer/script_context_set_unittest.cc b/extensions/renderer/script_context_set_unittest.cc
index 48eae81c..f0bf7b11 100644
--- a/extensions/renderer/script_context_set_unittest.cc
+++ b/extensions/renderer/script_context_set_unittest.cc
@@ -12,6 +12,7 @@
 #include "extensions/renderer/scoped_web_frame.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/script_context_set.h"
+#include "extensions/renderer/test_extensions_renderer_client.h"
 #include "gin/public/context_holder.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
@@ -22,6 +23,8 @@
 TEST(ScriptContextSetTest, Lifecycle) {
   base::MessageLoop loop;
   ScopedWebFrame web_frame;
+  // Used by ScriptContextSet::Register().
+  TestExtensionsRendererClient extensions_renderer_client;
 
   // Do this after construction of the webview, since it may construct the
   // Isolate.
@@ -36,8 +39,8 @@
 
   ExtensionIdSet active_extensions;
   ScriptContextSet context_set(&active_extensions);
-  ScriptContext* context = context_set.Register(
-      web_frame.frame(), v8_context, 0, 0);  // no extension group or world ID
+  ScriptContext* context =
+      context_set.Register(web_frame.frame(), v8_context, 0);  // no world ID
 
   // Context is valid and resembles correctness.
   EXPECT_TRUE(context->is_valid());
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc
index e7d0b90e..121def1 100644
--- a/extensions/renderer/script_injection.cc
+++ b/extensions/renderer/script_injection.cc
@@ -18,7 +18,6 @@
 #include "extensions/common/host_id.h"
 #include "extensions/renderer/dom_activity_logger.h"
 #include "extensions/renderer/extension_frame_helper.h"
-#include "extensions/renderer/extension_groups.h"
 #include "extensions/renderer/extensions_renderer_client.h"
 #include "extensions/renderer/script_injection_callback.h"
 #include "extensions/renderer/scripts_run_info.h"
@@ -278,7 +277,6 @@
         world_id,
         &sources.front(),
         sources.size(),
-        EXTENSION_GROUP_CONTENT_SCRIPTS,
         is_user_gesture,
         callback.release());
   }
diff --git a/extensions/renderer/test_extensions_renderer_client.cc b/extensions/renderer/test_extensions_renderer_client.cc
index 5299878ac..31c74a4 100644
--- a/extensions/renderer/test_extensions_renderer_client.cc
+++ b/extensions/renderer/test_extensions_renderer_client.cc
@@ -6,9 +6,13 @@
 
 namespace extensions {
 
-TestExtensionsRendererClient::TestExtensionsRendererClient() {}
+TestExtensionsRendererClient::TestExtensionsRendererClient() {
+  ExtensionsRendererClient::Set(this);
+}
 
-TestExtensionsRendererClient::~TestExtensionsRendererClient() {}
+TestExtensionsRendererClient::~TestExtensionsRendererClient() {
+  ExtensionsRendererClient::Set(nullptr);
+}
 
 bool TestExtensionsRendererClient::IsIncognitoProcess() const {
   return false;
diff --git a/ios/web/shell/test/BUILD.gn b/ios/web/shell/test/BUILD.gn
index 6b6db55..47e138e2 100644
--- a/ios/web/shell/test/BUILD.gn
+++ b/ios/web/shell/test/BUILD.gn
@@ -13,6 +13,7 @@
 }
 
 ios_eg_test("ios_web_shell_egtests") {
+  info_plist = "//ios/web/shell/Info.plist"
   sources = [
     "context_menu_egtest.mm",
     "meta_tags_egtest.mm",
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
index 77afc2c..7a8ea7f 100644
--- a/media/audio/BUILD.gn
+++ b/media/audio/BUILD.gn
@@ -62,6 +62,7 @@
     "audio_device_thread.h",
     "audio_features.cc",
     "audio_features.h",
+    "audio_file_writer.h",
     "audio_input_controller.cc",
     "audio_input_controller.h",
     "audio_input_device.cc",
diff --git a/media/audio/audio_input_writer.h b/media/audio/audio_file_writer.h
similarity index 78%
rename from media/audio/audio_input_writer.h
rename to media/audio/audio_file_writer.h
index 9e9f9a7..e7f8f48 100644
--- a/media/audio/audio_input_writer.h
+++ b/media/audio/audio_file_writer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MEDIA_AUDIO_AUDIO_INPUT_WRITER_H_
-#define MEDIA_AUDIO_AUDIO_INPUT_WRITER_H_
+#ifndef MEDIA_AUDIO_AUDIO_FILE_WRITER_H_
+#define MEDIA_AUDIO_AUDIO_FILE_WRITER_H_
 
 #include <memory>
 
@@ -11,11 +11,11 @@
 
 class AudioBus;
 
-// A writer interface used by AudioInputController for writing audio data to
-// file for debugging purposes.
-class AudioInputWriter {
+// A writer interface used for writing audio data to file for debugging
+// purposes.
+class AudioFileWriter {
  public:
-  virtual ~AudioInputWriter() {}
+  virtual ~AudioFileWriter() {}
 
   // Must be called before calling Write() for the first time after creation or
   // Stop() call. Can be called on any sequence; Write() and Stop() must be
@@ -38,4 +38,4 @@
 
 }  // namspace media
 
-#endif  // MEDIA_AUDIO_AUDIO_INPUT_WRITER_H_
+#endif  // MEDIA_AUDIO_AUDIO_FILE_WRITER_H_
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc
index 888df2c..878daf2 100644
--- a/media/audio/audio_input_controller.cc
+++ b/media/audio/audio_input_controller.cc
@@ -17,7 +17,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
-#include "media/audio/audio_input_writer.h"
+#include "media/audio/audio_file_writer.h"
 #include "media/base/user_input_monitor.h"
 
 namespace {
@@ -89,7 +89,7 @@
 AudioInputController::AudioInputController(
     EventHandler* handler,
     SyncWriter* sync_writer,
-    std::unique_ptr<AudioInputWriter> debug_writer,
+    std::unique_ptr<AudioFileWriter> debug_writer,
     UserInputMonitor* user_input_monitor,
     const bool agc_is_enabled)
     : creator_task_runner_(base::ThreadTaskRunnerHandle::Get()),
@@ -160,7 +160,7 @@
     const AudioParameters& params,
     const std::string& device_id,
     SyncWriter* sync_writer,
-    std::unique_ptr<AudioInputWriter> debug_writer,
+    std::unique_ptr<AudioFileWriter> debug_writer,
     UserInputMonitor* user_input_monitor,
     const bool agc_is_enabled) {
   DCHECK(audio_manager);
@@ -203,7 +203,7 @@
     EventHandler* event_handler,
     AudioInputStream* stream,
     SyncWriter* sync_writer,
-    std::unique_ptr<AudioInputWriter> debug_writer,
+    std::unique_ptr<AudioFileWriter> debug_writer,
     UserInputMonitor* user_input_monitor) {
   DCHECK(sync_writer);
   DCHECK(stream);
diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h
index 5d4a94a..ef691f1 100644
--- a/media/audio/audio_input_controller.h
+++ b/media/audio/audio_input_controller.h
@@ -81,7 +81,7 @@
 #define AUDIO_POWER_MONITORING
 #endif
 
-class AudioInputWriter;
+class AudioFileWriter;
 class UserInputMonitor;
 
 class MEDIA_EXPORT AudioInputController
@@ -185,7 +185,7 @@
       const std::string& device_id,
       // External synchronous writer for audio controller.
       SyncWriter* sync_writer,
-      std::unique_ptr<AudioInputWriter> debug_writer,
+      std::unique_ptr<AudioFileWriter> debug_writer,
       UserInputMonitor* user_input_monitor,
       const bool agc_is_enabled);
 
@@ -200,7 +200,7 @@
       AudioInputStream* stream,
       // External synchronous writer for audio controller.
       SyncWriter* sync_writer,
-      std::unique_ptr<AudioInputWriter> debug_writer,
+      std::unique_ptr<AudioFileWriter> debug_writer,
       UserInputMonitor* user_input_monitor);
 
   // Starts recording using the created audio input stream.
@@ -289,7 +289,7 @@
 
   AudioInputController(EventHandler* handler,
                        SyncWriter* sync_writer,
-                       std::unique_ptr<AudioInputWriter> debug_writer,
+                       std::unique_ptr<AudioFileWriter> debug_writer,
                        UserInputMonitor* user_input_monitor,
                        const bool agc_is_enabled);
   ~AudioInputController() override;
@@ -392,7 +392,7 @@
   base::TimeTicks low_latency_create_time_;
 
   // Used for audio debug recordings. Accessed on audio thread.
-  const std::unique_ptr<AudioInputWriter> debug_writer_;
+  const std::unique_ptr<AudioFileWriter> debug_writer_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AudioInputController);
diff --git a/media/audio/test_audio_input_controller_factory.cc b/media/audio/test_audio_input_controller_factory.cc
index 024e7ad..fb70e32a 100644
--- a/media/audio/test_audio_input_controller_factory.cc
+++ b/media/audio/test_audio_input_controller_factory.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "media/audio/test_audio_input_controller_factory.h"
-#include "media/audio/audio_input_writer.h"
+#include "media/audio/audio_file_writer.h"
 #include "media/audio/audio_io.h"
 
 namespace media {
diff --git a/net/cert/cert_net_fetcher.h b/net/cert/cert_net_fetcher.h
index 56a7494..2a45fe3 100644
--- a/net/cert/cert_net_fetcher.h
+++ b/net/cert/cert_net_fetcher.h
@@ -20,16 +20,15 @@
 namespace net {
 
 // CertNetFetcher is a synchronous interface for fetching AIA URLs and CRL
-// URLs.
+// URLs. It is shared between a caller thread (which starts and waits for
+// fetches), and a network thread (which does the actual fetches). It can be
+// shutdown from the network thread to cancel outstanding requests.
 //
 // A Request object is returned when starting a fetch. The consumer can
 // use this as a handle for aborting the request (by freeing it), or reading
 // the result of the request (WaitForResult)
-//
-// This interface is expected to be operated from a single thread.
-//
-// The CertNetFetcher must outlive all Request objects it creates.
-class NET_EXPORT CertNetFetcher {
+class NET_EXPORT CertNetFetcher
+    : public base::RefCountedThreadSafe<CertNetFetcher> {
  public:
   class Request {
    public:
@@ -47,7 +46,12 @@
 
   CertNetFetcher() {}
 
-  virtual ~CertNetFetcher() {}
+  // Shuts down the CertNetFetcher and cancels outstanding network requests. It
+  // is not guaranteed that any outstanding or subsequent
+  // Request::WaitForResult() calls will be completed. Shutdown() must be called
+  // from the network thread. It can be called more than once, but must be
+  // called before the CertNetFetcher is destroyed.
+  virtual void Shutdown() = 0;
 
   // The Fetch*() methods start a request which can be cancelled by
   // deleting the returned Request. Here is the meaning of the common
@@ -76,7 +80,11 @@
       int timeout_milliseconds,
       int max_response_bytes) = 0;
 
+ protected:
+  virtual ~CertNetFetcher() {}
+
  private:
+  friend class base::RefCountedThreadSafe<CertNetFetcher>;
   DISALLOW_COPY_AND_ASSIGN(CertNetFetcher);
 };
 
diff --git a/net/cert/internal/cert_issuer_source_aia.cc b/net/cert/internal/cert_issuer_source_aia.cc
index 589b724..6e1290a 100644
--- a/net/cert/internal/cert_issuer_source_aia.cc
+++ b/net/cert/internal/cert_issuer_source_aia.cc
@@ -93,8 +93,9 @@
 
 }  // namespace
 
-CertIssuerSourceAia::CertIssuerSourceAia(CertNetFetcher* cert_fetcher)
-    : cert_fetcher_(cert_fetcher) {}
+CertIssuerSourceAia::CertIssuerSourceAia(
+    scoped_refptr<CertNetFetcher> cert_fetcher)
+    : cert_fetcher_(std::move(cert_fetcher)) {}
 
 CertIssuerSourceAia::~CertIssuerSourceAia() = default;
 
diff --git a/net/cert/internal/cert_issuer_source_aia.h b/net/cert/internal/cert_issuer_source_aia.h
index 878b18b..3e62c95 100644
--- a/net/cert/internal/cert_issuer_source_aia.h
+++ b/net/cert/internal/cert_issuer_source_aia.h
@@ -16,10 +16,10 @@
 class NET_EXPORT CertIssuerSourceAia : public CertIssuerSource {
  public:
   // Creates CertIssuerSource that will use |cert_fetcher| to retrieve issuers
-  // using AuthorityInfoAccess URIs. |cert_fetcher| must outlive the
-  // CertIssuerSourceAia.  CertIssuerSourceAia must be created and used only on
-  // a single thread, which is the thread |cert_fetcher| will be operated from.
-  explicit CertIssuerSourceAia(CertNetFetcher* cert_fetcher);
+  // using AuthorityInfoAccess URIs. CertIssuerSourceAia must be created and
+  // used only on a single thread, which is the thread |cert_fetcher| will be
+  // operated from.
+  explicit CertIssuerSourceAia(scoped_refptr<CertNetFetcher> cert_fetcher);
   ~CertIssuerSourceAia() override;
 
   // CertIssuerSource implementation:
@@ -29,7 +29,7 @@
                          std::unique_ptr<Request>* out_req) override;
 
  private:
-  CertNetFetcher* cert_fetcher_;
+  scoped_refptr<CertNetFetcher> cert_fetcher_;
 
   DISALLOW_COPY_AND_ASSIGN(CertIssuerSourceAia);
 };
diff --git a/net/cert/internal/cert_issuer_source_aia_unittest.cc b/net/cert/internal/cert_issuer_source_aia_unittest.cc
index 87a5795..f81c33d 100644
--- a/net/cert/internal/cert_issuer_source_aia_unittest.cc
+++ b/net/cert/internal/cert_issuer_source_aia_unittest.cc
@@ -63,6 +63,8 @@
 // MockCertNetFetcher is an implementation of CertNetFetcher for testing.
 class MockCertNetFetcher : public CertNetFetcher {
  public:
+  MockCertNetFetcher() {}
+  MOCK_METHOD0(Shutdown, void());
   MOCK_METHOD3(FetchCaIssuers,
                std::unique_ptr<Request>(const GURL& url,
                                         int timeout_milliseconds,
@@ -76,6 +78,9 @@
                std::unique_ptr<Request>(const GURL& url,
                                         int timeout_milliseconds,
                                         int max_response_bytes));
+
+ protected:
+  ~MockCertNetFetcher() override {}
 };
 
 // MockCertNetFetcherRequest gives back the indicated error and bytes.
@@ -116,8 +121,8 @@
   ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
 
   // No methods on |mock_fetcher| should be called.
-  StrictMock<MockCertNetFetcher> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   ParsedCertificateList issuers;
   aia_source.SyncGetIssuersOf(cert.get(), &issuers);
   EXPECT_EQ(0U, issuers.size());
@@ -130,8 +135,8 @@
   ASSERT_TRUE(ReadTestCert("target_no_aia.pem", &cert));
 
   // No methods on |mock_fetcher| should be called.
-  StrictMock<MockCertNetFetcher> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> request;
   aia_source.AsyncGetIssuersOf(cert.get(), &request);
   EXPECT_EQ(nullptr, request);
@@ -146,11 +151,11 @@
   scoped_refptr<ParsedCertificate> cert;
   ASSERT_TRUE(ReadTestCert("target_file_aia.pem", &cert));
 
-  StrictMock<MockCertNetFetcher> mock_fetcher;
-  EXPECT_CALL(mock_fetcher, FetchCaIssuers(GURL("file:///dev/null"), _, _))
+  auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
+  EXPECT_CALL(*mock_fetcher, FetchCaIssuers(GURL("file:///dev/null"), _, _))
       .WillOnce(Return(ByMove(CreateMockRequest(ERR_DISALLOWED_URL_SCHEME))));
 
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(), &cert_source_request);
   ASSERT_NE(nullptr, cert_source_request);
@@ -167,8 +172,8 @@
   scoped_refptr<ParsedCertificate> cert;
   ASSERT_TRUE(ReadTestCert("target_invalid_url_aia.pem", &cert));
 
-  StrictMock<MockCertNetFetcher> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> request;
   aia_source.AsyncGetIssuersOf(cert.get(), &request);
   EXPECT_EQ(nullptr, request);
@@ -181,14 +186,14 @@
   scoped_refptr<ParsedCertificate> intermediate_cert;
   ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
 
-  StrictMock<MockCertNetFetcher> mock_fetcher;
+  auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
 
-  EXPECT_CALL(mock_fetcher,
+  EXPECT_CALL(*mock_fetcher,
               FetchCaIssuers(GURL("http://url-for-aia/I.cer"), _, _))
       .WillOnce(Return(
           ByMove(CreateMockRequest(CertDataVector(intermediate_cert.get())))));
 
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(), &cert_source_request);
   ASSERT_NE(nullptr, cert_source_request);
@@ -213,17 +218,17 @@
   scoped_refptr<ParsedCertificate> intermediate_cert;
   ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert));
 
-  StrictMock<MockCertNetFetcher> mock_fetcher;
+  auto mock_fetcher = make_scoped_refptr(new StrictMock<MockCertNetFetcher>());
 
-  EXPECT_CALL(mock_fetcher, FetchCaIssuers(GURL("file:///dev/null"), _, _))
+  EXPECT_CALL(*mock_fetcher, FetchCaIssuers(GURL("file:///dev/null"), _, _))
       .WillOnce(Return(ByMove(CreateMockRequest(ERR_DISALLOWED_URL_SCHEME))));
 
-  EXPECT_CALL(mock_fetcher,
+  EXPECT_CALL(*mock_fetcher,
               FetchCaIssuers(GURL("http://url-for-aia2/I2.foo"), _, _))
       .WillOnce(Return(
           ByMove(CreateMockRequest(CertDataVector(intermediate_cert.get())))));
 
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(), &cert_source_request);
   ASSERT_NE(nullptr, cert_source_request);
@@ -247,8 +252,9 @@
   ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
@@ -292,8 +298,9 @@
   ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
@@ -368,8 +375,9 @@
   ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
@@ -440,8 +448,9 @@
   ASSERT_TRUE(ReadTestCert("i3.pem", &intermediate_cert3));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
@@ -516,8 +525,9 @@
   ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
@@ -550,8 +560,9 @@
   ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
@@ -585,8 +596,9 @@
   ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
@@ -639,8 +651,9 @@
   ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
@@ -697,8 +710,9 @@
   ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
@@ -733,8 +747,9 @@
   ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
@@ -784,8 +799,9 @@
   ASSERT_TRUE(ReadTestCert("target_six_aia.pem", &cert));
 
   StrictMock<MockIssuerCallback> mock_callback;
-  StrictMock<MockCertNetFetcherImpl> mock_fetcher;
-  CertIssuerSourceAia aia_source(&mock_fetcher);
+  scoped_refptr<StrictMock<MockCertNetFetcherImpl>> mock_fetcher(
+      new StrictMock<MockCertNetFetcherImpl>());
+  CertIssuerSourceAia aia_source(mock_fetcher);
   std::unique_ptr<CertIssuerSource::Request> cert_source_request;
   aia_source.AsyncGetIssuersOf(cert.get(),
                                base::Bind(&MockIssuerCallback::Callback,
diff --git a/net/cert_net/cert_net_fetcher_impl.cc b/net/cert_net/cert_net_fetcher_impl.cc
index bedd2af..50cc66c 100644
--- a/net/cert_net/cert_net_fetcher_impl.cc
+++ b/net/cert_net/cert_net_fetcher_impl.cc
@@ -13,33 +13,23 @@
 // caller can use to cancel the fetch, or wait for it to complete
 // (blocking).
 //
+// The CertNetFetcherImpl is shared between a network thread and a
+// caller thread that waits for fetches to happen on the network thread.
+//
 // The classes are mainly organized based on their thread affinity:
 //
 // ---------------
-// Lives on caller thread
-// ---------------
-//
-// CertNetFetcherImpl (implements CertNetFetcher)
-//   * Main entry point
-//   * Provides a service to start/cancel/wait for URL fetches
-//   * Returns callers a CertNetFetcher::Request as a handle
-//   * Requests can run in parallel, however will block the current thread when
-//     reading results.
-//   * Posts tasks to network thread to coordinate actual work
-//
-// CertNetFetcherRequestImpl (implements CertNetFetcher::Request)
-//   * Wrapper for cancelling events, or waiting for a request to complete
-//   * Waits on a WaitableEvent to complete requests.
-//
-// ---------------
 // Straddles caller thread and network thread
 // ---------------
 //
-// CertNetFetcherCore
-//   * Reference-counted bridge between CertNetFetcherImpl and the dependencies
-//     on network thread.
-//   * Small wrapper to holds the state that is conceptually owned by
-//     CertNetFetcherImpl, but belongs on the network thread.
+// CertNetFetcherImpl (implements CertNetFetcher)
+//   * Main entry point. Must be created and shutdown from the network thread.
+//   * Provides a service to start/cancel/wait for URL fetches, to be
+//     used on the caller thread.
+//   * Returns callers a CertNetFetcher::Request as a handle
+//   * Requests can run in parallel, however will block the current thread when
+//     reading results.
+//   * Posts tasks to network thread to coordinate actual work
 //
 // RequestCore
 //   * Reference-counted bridge between CertNetFetcherRequestImpl and the
@@ -48,6 +38,14 @@
 //     completion, and pointers for canceling work on network thread.
 //
 // ---------------
+// Lives on caller thread
+// ---------------
+//
+// CertNetFetcherRequestImpl (implements CertNetFetcher::Request)
+//   * Wrapper for cancelling events, or waiting for a request to complete
+//   * Waits on a WaitableEvent to complete requests.
+//
+// ---------------
 // Lives on network thread
 // ---------------
 //
@@ -69,12 +67,12 @@
 #include "base/memory/ptr_util.h"
 #include "base/numerics/safe_math.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "base/timer/timer.h"
 #include "net/base/load_flags.h"
 #include "net/cert/cert_net_fetcher.h"
 #include "net/url_request/redirect_info.h"
 #include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
 
 // TODO(eroman): Add support for POST parameters.
 // TODO(eroman): Add controls for bypassing the cache.
@@ -121,21 +119,22 @@
 class AsyncCertNetFetcherImpl {
  public:
   // Initializes AsyncCertNetFetcherImpl using the specified URLRequestContext
-  // for issuing requests. |context| must remain valid for the entire
-  // lifetime of the AsyncCertNetFetcherImpl.
+  // for issuing requests. |context| must remain valid until Shutdown() is
+  // called or the AsyncCertNetFetcherImpl is destroyed.
   explicit AsyncCertNetFetcherImpl(URLRequestContext* context);
 
-  // Deletion implicitly cancels any outstanding requests.
+  // The AsyncCertNetFetcherImpl is expected to be kept alive until all
+  // requests have completed or Shutdown() is called.
   ~AsyncCertNetFetcherImpl();
 
   // Starts an asynchronous request to fetch the given URL. On completion
-  // |callback| will be invoked.
-  //
-  // Completion of the request will never occur synchronously. In other words it
-  // is guaranteed that |callback| will only be invoked once the Fetch*() method
-  // has returned.
+  // request->OnJobCompleted() will be invoked.
   void Fetch(std::unique_ptr<RequestParams> request_params,
-             RequestCore* request);
+             scoped_refptr<RequestCore> request);
+
+  // Cancels outstanding jobs, which stops network requests and signals the
+  // corresponding RequestCores that the requests have completed.
+  void Shutdown();
 
  private:
   friend class Job;
@@ -206,6 +205,10 @@
   void AttachedToJob(Job* job) {
     DCHECK(task_runner_->RunsTasksOnCurrentThread());
     DCHECK(!job_);
+    // Requests should not be attached to jobs after they have been signalled
+    // with a cancellation error (which happens via either Cancel() or
+    // SignalImmediateError()).
+    DCHECK_NE(error_, ERR_ABORTED);
     job_ = job;
   }
 
@@ -222,8 +225,13 @@
     completion_event_.Signal();
   }
 
-  // Can be called from any thread.
-  void Cancel();
+  // Detaches this request from its job (if it is attached to any) and
+  // signals completion with ERR_ABORTED. Can be called from any thread.
+  void CancelJob();
+
+  // Can be used to signal that an error was encountered before the request was
+  // attached to a job. Can be called from any thread.
+  void SignalImmediateError();
 
   // Should only be called once.
   void WaitForResult(Error* error, std::vector<uint8_t>* bytes) {
@@ -247,7 +255,10 @@
   // A non-owned pointer to the job that is executing the request.
   Job* job_ = nullptr;
 
-  // May be written to from network thread.
+  // May be written to from network thread, or from the caller thread only when
+  // there is no work that will be done on the network thread (e.g. when the
+  // network thread has been shutdown before the request begins). See comment in
+  // SignalImmediateError.
   Error error_;
   std::vector<uint8_t> bytes_;
 
@@ -296,10 +307,9 @@
 
   const RequestParams& request_params() const { return *request_params_; }
 
-  // Create a request and attaches it to the job. When the job completes it will
-  // notify the request of completion through OnJobCompleted. Note that the Job
-  // does NOT own the request.
-  void AttachRequest(RequestCore* request);
+  // Creates a request and attaches it to the job. When the job completes it
+  // will notify the request of completion through OnJobCompleted.
+  void AttachRequest(scoped_refptr<RequestCore> request);
 
   // Removes |request| from the job.
   void DetachRequest(RequestCore* request);
@@ -309,6 +319,11 @@
   // notified of completion.
   void StartURLRequest(URLRequestContext* context);
 
+  // Cancels the request with an ERR_ABORTED error and invokes
+  // RequestCore::OnJobCompleted() to notify the registered requests of the
+  // cancellation. The job is *not* removed from the AsyncCertNetFetcherImpl.
+  void Cancel();
+
  private:
   // Implementation of URLRequest::Delegate
   void OnReceivedRedirect(URLRequest* request,
@@ -336,12 +351,16 @@
   // method is called, the |response_body_| variable have been assigned.
   void OnJobCompleted(Error error);
 
+  // Calls r->OnJobCompleted() for each RequestCore |r| currently attached
+  // to this job, and then clears |requests_|.
+  void CompleteAndClearRequests(Error error);
+
   // Cancels a request with a specified error code and calls
   // OnUrlRequestCompleted().
   void FailRequest(Error error);
 
-  // The requests attached to this job (non-owned).
-  std::vector<RequestCore*> requests_;
+  // The requests attached to this job.
+  std::vector<scoped_refptr<RequestCore>> requests_;
 
   // The input parameters for starting a URLRequest.
   std::unique_ptr<RequestParams> request_params_;
@@ -362,9 +381,10 @@
   DISALLOW_COPY_AND_ASSIGN(Job);
 };
 
-void RequestCore::Cancel() {
+void RequestCore::CancelJob() {
   if (!task_runner_->RunsTasksOnCurrentThread()) {
-    task_runner_->PostTask(FROM_HERE, base::Bind(&RequestCore::Cancel, this));
+    task_runner_->PostTask(FROM_HERE,
+                           base::Bind(&RequestCore::CancelJob, this));
     return;
   }
 
@@ -374,8 +394,23 @@
     job->DetachRequest(this);
   }
 
+  SignalImmediateError();
+}
+
+void RequestCore::SignalImmediateError() {
+  // These data members are normally only written on the network thread, but it
+  // is safe to write here from either thread. This is because
+  // SignalImmediateError is only to be called before this request is attached
+  // to a job. In particular, if called from the caller thread, no work will be
+  // done on the network thread for this request, so these variables will only
+  // be written and read on the caller thread. If called from the network
+  // thread, they will only be written to on the network thread and will not be
+  // read on the caller thread until |completion_event_| is signalled (after
+  // which it will be not be written on the network thread again).
+  DCHECK(!job_);
+  error_ = ERR_ABORTED;
   bytes_.clear();
-  error_ = ERR_UNEXPECTED;
+  completion_event_.Signal();
 }
 
 Job::Job(std::unique_ptr<RequestParams> request_params,
@@ -387,9 +422,9 @@
   Stop();
 }
 
-void Job::AttachRequest(RequestCore* request) {
-  requests_.push_back(request);
+void Job::AttachRequest(scoped_refptr<RequestCore> request) {
   request->AttachedToJob(this);
+  requests_.push_back(std::move(request));
 }
 
 void Job::DetachRequest(RequestCore* request) {
@@ -408,10 +443,7 @@
 void Job::StartURLRequest(URLRequestContext* context) {
   Error error = CanFetchUrl(request_params_->url);
   if (error != OK) {
-    // TODO(eroman): Don't post a task for this case.
-    timer_.Start(
-        FROM_HERE, base::TimeDelta(),
-        base::Bind(&Job::OnJobCompleted, base::Unretained(this), error));
+    OnJobCompleted(error);
     return;
   }
 
@@ -432,6 +464,13 @@
         base::Bind(&Job::FailRequest, base::Unretained(this), ERR_TIMED_OUT));
 }
 
+void Job::Cancel() {
+  // Stop the timer and clear the URLRequest.
+  Stop();
+  // Signal attached requests that they've been completed.
+  CompleteAndClearRequests(static_cast<Error>(ERR_ABORTED));
+}
+
 void Job::OnReceivedRedirect(URLRequest* request,
                              const RedirectInfo& redirect_info,
                              bool* defer_redirect) {
@@ -524,8 +563,11 @@
   Stop();
 
   std::unique_ptr<Job> delete_this = parent_->RemoveJob(this);
+  CompleteAndClearRequests(error);
+}
 
-  for (auto* request : requests_) {
+void Job::CompleteAndClearRequests(Error error) {
+  for (const auto& request : requests_) {
     request->OnJobCompleted(this, error, response_body_);
   }
 
@@ -555,20 +597,32 @@
 
 void AsyncCertNetFetcherImpl::Fetch(
     std::unique_ptr<RequestParams> request_params,
-    RequestCore* request) {
+    scoped_refptr<RequestCore> request) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   // If there is an in-progress job that matches the request parameters use it.
   // Otherwise start a new job.
   Job* job = FindJob(*request_params);
-
-  if (!job) {
-    job = new Job(std::move(request_params), this);
-    jobs_[job] = base::WrapUnique(job);
-    job->StartURLRequest(context_);
+  if (job) {
+    job->AttachRequest(std::move(request));
+    return;
   }
 
-  return job->AttachRequest(request);
+  job = new Job(std::move(request_params), this);
+  jobs_[job] = base::WrapUnique(job);
+  // Attach the request before calling StartURLRequest; this ensures that the
+  // request will get signalled if StartURLRequest completes the job
+  // synchronously.
+  job->AttachRequest(std::move(request));
+  job->StartURLRequest(context_);
+}
+
+void AsyncCertNetFetcherImpl::Shutdown() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  for (const auto& job : jobs_) {
+    job.first->Cancel();
+  }
+  jobs_.clear();
 }
 
 struct JobToRequestParamsComparator {
@@ -615,66 +669,26 @@
 
   ~CertNetFetcherRequestImpl() override {
     if (core_)
-      core_->Cancel();
+      core_->CancelJob();
   }
 
  private:
   scoped_refptr<RequestCore> core_;
 };
 
-class CertNetFetcherCore
-    : public base::RefCountedThreadSafe<CertNetFetcherCore> {
- public:
-  explicit CertNetFetcherCore(URLRequestContextGetter* context_getter)
-      : context_getter_(context_getter) {}
-
-  void Abandon() {
-    GetNetworkTaskRunner()->PostTask(
-        FROM_HERE,
-        base::Bind(&CertNetFetcherCore::DoAbandonOnNetworkThread, this));
-  }
-
-  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() {
-    return context_getter_->GetNetworkTaskRunner();
-  }
-
-  void DoFetchOnNetworkThread(std::unique_ptr<RequestParams> request_params,
-                              scoped_refptr<RequestCore> request) {
-    DCHECK(GetNetworkTaskRunner()->RunsTasksOnCurrentThread());
-
-    if (!impl_) {
-      impl_.reset(
-          new AsyncCertNetFetcherImpl(context_getter_->GetURLRequestContext()));
-    }
-
-    // Don't need to retain a reference to |request| because consume is
-    // expected to keep it alive.
-    impl_->Fetch(std::move(request_params), request.get());
-  }
-
- private:
-  friend class base::RefCountedThreadSafe<CertNetFetcherCore>;
-
-  void DoAbandonOnNetworkThread() {
-    DCHECK(GetNetworkTaskRunner()->RunsTasksOnCurrentThread());
-    impl_.reset();
-  }
-
-  ~CertNetFetcherCore() { DCHECK(!impl_); }
-
-  scoped_refptr<URLRequestContextGetter> context_getter_;
-
-  std::unique_ptr<AsyncCertNetFetcherImpl> impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(CertNetFetcherCore);
-};
-
 class CertNetFetcherImpl : public CertNetFetcher {
  public:
-  explicit CertNetFetcherImpl(URLRequestContextGetter* context_getter)
-      : core_(new CertNetFetcherCore(context_getter)) {}
+  explicit CertNetFetcherImpl(URLRequestContext* context)
+      : task_runner_(base::ThreadTaskRunnerHandle::Get()), context_(context) {}
 
-  ~CertNetFetcherImpl() override { core_->Abandon(); }
+  void Shutdown() override {
+    DCHECK(task_runner_->RunsTasksOnCurrentThread());
+    if (impl_) {
+      impl_->Shutdown();
+      impl_.reset();
+    }
+    context_ = nullptr;
+  }
 
   std::unique_ptr<Request> FetchCaIssuers(const GURL& url,
                                           int timeout_milliseconds,
@@ -720,28 +734,60 @@
   }
 
  private:
+  ~CertNetFetcherImpl() override {
+    // The fetcher must be shutdown (at which point |context_| will be set to
+    // null) before destruction.
+    DCHECK(!context_);
+  }
+
+  void DoFetchOnNetworkThread(std::unique_ptr<RequestParams> request_params,
+                              scoped_refptr<RequestCore> request) {
+    DCHECK(task_runner_->RunsTasksOnCurrentThread());
+
+    if (!context_) {
+      // The fetcher might have been shutdown between when this task was posted
+      // and when it is running. In this case, signal the request and do not
+      // start a network request.
+      request->SignalImmediateError();
+      return;
+    }
+
+    if (!impl_) {
+      impl_.reset(new AsyncCertNetFetcherImpl(context_));
+    }
+
+    impl_->Fetch(std::move(request_params), request);
+  }
+
   std::unique_ptr<Request> DoFetch(
       std::unique_ptr<RequestParams> request_params) {
-    auto task_runner = core_->GetNetworkTaskRunner();
-    scoped_refptr<RequestCore> request_core = new RequestCore(task_runner);
+    scoped_refptr<RequestCore> request_core = new RequestCore(task_runner_);
 
-    task_runner->PostTask(
-        FROM_HERE,
-        base::Bind(&CertNetFetcherCore::DoFetchOnNetworkThread, core_,
-                   base::Passed(&request_params), request_core));
+    // If the fetcher has already been shutdown, DoFetchOnNetworkThread will
+    // signal the request with an error. However, if the fetcher shuts down
+    // before DoFetchOnNetworkThread runs and PostTask still returns true, then
+    // the request will hang (that is, WaitForResult will not return).
+    if (!task_runner_->PostTask(
+            FROM_HERE,
+            base::Bind(&CertNetFetcherImpl::DoFetchOnNetworkThread, this,
+                       base::Passed(&request_params), request_core))) {
+      request_core->SignalImmediateError();
+    }
 
     return base::MakeUnique<CertNetFetcherRequestImpl>(std::move(request_core));
   }
 
  private:
-  scoped_refptr<CertNetFetcherCore> core_;
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  // Not owned. |context_| must stay valid until Shutdown() is called.
+  URLRequestContext* context_ = nullptr;
+  std::unique_ptr<AsyncCertNetFetcherImpl> impl_;
 };
 
 }  // namespace
 
-std::unique_ptr<CertNetFetcher> CreateCertNetFetcher(
-    URLRequestContextGetter* context_getter) {
-  return base::MakeUnique<CertNetFetcherImpl>(context_getter);
+scoped_refptr<CertNetFetcher> CreateCertNetFetcher(URLRequestContext* context) {
+  return make_scoped_refptr(new CertNetFetcherImpl(context));
 }
 
 }  // namespace net
diff --git a/net/cert_net/cert_net_fetcher_impl.h b/net/cert_net/cert_net_fetcher_impl.h
index d4add24..c863fda7 100644
--- a/net/cert_net/cert_net_fetcher_impl.h
+++ b/net/cert_net/cert_net_fetcher_impl.h
@@ -7,21 +7,21 @@
 
 #include <memory>
 
+#include "base/memory/ref_counted.h"
 #include "net/base/net_export.h"
 
 namespace net {
 
 class CertNetFetcher;
-class URLRequestContextGetter;
+class URLRequestContext;
 
 // Creates a CertNetFetcher that issues requests through the provided
-// URLRequestContext.
-//
-// The returned CertNetFetcher is to be operated on a thread *other* than the
-// thread used for the URLRequestContext (since it gives a blocking interface
-// to URL fetching).
-NET_EXPORT std::unique_ptr<CertNetFetcher> CreateCertNetFetcher(
-    URLRequestContextGetter* context_getter);
+// URLRequestContext. The URLRequestContext must stay valid until the returned
+// CertNetFetcher's Shutdown method is called. The CertNetFetcher is to be
+// created and shutdown on the network thread. Its Fetch methods are to be used
+// on a *different* thread, since it gives a blocking interface to URL fetching.
+NET_EXPORT scoped_refptr<CertNetFetcher> CreateCertNetFetcher(
+    URLRequestContext* context);
 
 }  // namespace net
 
diff --git a/net/cert_net/cert_net_fetcher_impl_unittest.cc b/net/cert_net/cert_net_fetcher_impl_unittest.cc
index a6b383e..99f5770 100644
--- a/net/cert_net/cert_net_fetcher_impl_unittest.cc
+++ b/net/cert_net/cert_net_fetcher_impl_unittest.cc
@@ -19,6 +19,8 @@
 #include "net/http/http_server_properties_impl.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/gtest_util.h"
+#include "net/test/url_request/url_request_hanging_read_job.h"
+#include "net/url_request/url_request_filter.h"
 #include "net/url_request/url_request_job_factory_impl.h"
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -113,6 +115,8 @@
   }
 
   ~CertNetFetcherImplTest() override {
+    if (!network_thread_)
+      return;
     network_thread_->task_runner()->PostTask(
         FROM_HERE, base::Bind(&CertNetFetcherImplTest::TeardownOnNetworkThread,
                               base::Unretained(this)));
@@ -120,11 +124,36 @@
   }
 
  protected:
-  std::unique_ptr<CertNetFetcher> CreateFetcher() {
-    scoped_refptr<TrivialURLRequestContextGetter> context_getter(
-        new TrivialURLRequestContextGetter(&state_->context,
-                                           network_thread_->task_runner()));
-    return CreateCertNetFetcher(context_getter.get());
+  CertNetFetcher* fetcher() const { return fetcher_.get(); }
+
+  void CreateFetcherOnNetworkThread(base::WaitableEvent* done) {
+    fetcher_ = CreateCertNetFetcher(&state_->context);
+    done->Signal();
+  }
+
+  void CreateFetcher() {
+    base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
+                             base::WaitableEvent::InitialState::NOT_SIGNALED);
+    network_thread_->task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&CertNetFetcherImplTest::CreateFetcherOnNetworkThread,
+                   base::Unretained(this), &done));
+    done.Wait();
+  }
+
+  void ShutDownFetcherOnNetworkThread(base::WaitableEvent* done) {
+    fetcher_->Shutdown();
+    done->Signal();
+  }
+
+  void ShutDownFetcher() {
+    base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
+                             base::WaitableEvent::InitialState::NOT_SIGNALED);
+    network_thread_->task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&CertNetFetcherImplTest::ShutDownFetcherOnNetworkThread,
+                   base::Unretained(this), &done));
+    done.Wait();
   }
 
   int NumCreatedRequests() {
@@ -159,7 +188,26 @@
     done->Signal();
   }
 
-  void TeardownOnNetworkThread() { state_.reset(); }
+  void ResetStateOnNetworkThread(base::WaitableEvent* done) {
+    state_.reset();
+    done->Signal();
+  }
+
+  void ResetState() {
+    base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
+                             base::WaitableEvent::InitialState::NOT_SIGNALED);
+    network_thread_->task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&CertNetFetcherImplTest::ResetStateOnNetworkThread,
+                   base::Unretained(this), &done));
+    done.Wait();
+  }
+
+  void TeardownOnNetworkThread() {
+    fetcher_->Shutdown();
+    state_.reset();
+    fetcher_ = nullptr;
+  }
 
   void CountCreatedRequests(int* count, base::WaitableEvent* done) {
     *count = state_->network_delegate.created_requests();
@@ -168,10 +216,20 @@
 
   EmbeddedTestServer test_server_;
   std::unique_ptr<base::Thread> network_thread_;
+  scoped_refptr<CertNetFetcher> fetcher_;
 
   std::unique_ptr<NetworkThreadState> state_;
 };
 
+// Installs URLRequestHangingReadJob handlers and clears them on teardown.
+class CertNetFetcherImplTestWithHangingReadHandler
+    : public CertNetFetcherImplTest {
+ protected:
+  void SetUp() override { URLRequestHangingReadJob::AddUrlHandler(); }
+
+  void TearDown() override { URLRequestFilter::GetInstance()->ClearHandlers(); }
+};
+
 // Helper to start an AIA fetch using default parameters.
 WARN_UNUSED_RESULT std::unique_ptr<CertNetFetcher::Request> StartRequest(
     CertNetFetcher* fetcher,
@@ -184,23 +242,22 @@
 // and Content-Type.
 TEST_F(CertNetFetcherImplTest, ParallelFetchNoDuplicates) {
   ASSERT_TRUE(test_server_.Start());
-
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   // Request a URL with Content-Type "application/pkix-cert"
   GURL url1 = test_server_.GetURL("/cert.crt");
   std::unique_ptr<CertNetFetcher::Request> request1 =
-      StartRequest(fetcher.get(), url1);
+      StartRequest(fetcher(), url1);
 
   // Request a URL with Content-Type "application/pkix-crl"
   GURL url2 = test_server_.GetURL("/root.crl");
   std::unique_ptr<CertNetFetcher::Request> request2 =
-      StartRequest(fetcher.get(), url2);
+      StartRequest(fetcher(), url2);
 
   // Request a URL with Content-Type "application/pkcs7-mime"
   GURL url3 = test_server_.GetURL("/certs.p7c");
   std::unique_ptr<CertNetFetcher::Request> request3 =
-      StartRequest(fetcher.get(), url3);
+      StartRequest(fetcher(), url3);
 
   // Wait for all of the requests to complete and verify the fetch results.
   VerifySuccess("-cert.crt-\n", request1.get());
@@ -216,12 +273,11 @@
 // be meaningful.
 TEST_F(CertNetFetcherImplTest, ContentTypeDoesntMatter) {
   ASSERT_TRUE(test_server_.Start());
-
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url = test_server_.GetURL("/foo.txt");
   std::unique_ptr<CertNetFetcher::Request> request =
-      StartRequest(fetcher.get(), url);
+      StartRequest(fetcher(), url);
   VerifySuccess("-foo.txt-\n", request.get());
 }
 
@@ -229,14 +285,13 @@
 // failures.
 TEST_F(CertNetFetcherImplTest, HttpStatusCode) {
   ASSERT_TRUE(test_server_.Start());
-
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   // Response was HTTP status 404.
   {
     GURL url = test_server_.GetURL("/404.html");
     std::unique_ptr<CertNetFetcher::Request> request =
-        StartRequest(fetcher.get(), url);
+        StartRequest(fetcher(), url);
     VerifyFailure(ERR_FAILED, request.get());
   }
 
@@ -244,7 +299,7 @@
   {
     GURL url = test_server_.GetURL("/500.html");
     std::unique_ptr<CertNetFetcher::Request> request =
-        StartRequest(fetcher.get(), url);
+        StartRequest(fetcher(), url);
     VerifyFailure(ERR_FAILED, request.get());
   }
 }
@@ -252,12 +307,11 @@
 // Fetching a URL with a Content-Disposition header should have no effect.
 TEST_F(CertNetFetcherImplTest, ContentDisposition) {
   ASSERT_TRUE(test_server_.Start());
-
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url = test_server_.GetURL("/downloadable.js");
   std::unique_ptr<CertNetFetcher::Request> request =
-      StartRequest(fetcher.get(), url);
+      StartRequest(fetcher(), url);
   VerifySuccess("-downloadable.js-\n", request.get());
 }
 
@@ -266,13 +320,13 @@
 TEST_F(CertNetFetcherImplTest, Cache) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   // Fetch a URL whose HTTP headers make it cacheable for 1 hour.
   GURL url(test_server_.GetURL("/cacheable_1hr.crt"));
   {
     std::unique_ptr<CertNetFetcher::Request> request =
-        StartRequest(fetcher.get(), url);
+        StartRequest(fetcher(), url);
     VerifySuccess("-cacheable_1hr.crt-\n", request.get());
   }
 
@@ -284,7 +338,7 @@
   // Fetch again -- will fail unless served from cache.
   {
     std::unique_ptr<CertNetFetcher::Request> request =
-        StartRequest(fetcher.get(), url);
+        StartRequest(fetcher(), url);
     VerifySuccess("-cacheable_1hr.crt-\n", request.get());
   }
 
@@ -296,13 +350,13 @@
 TEST_F(CertNetFetcherImplTest, TooLarge) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   // This file has a response body 12 bytes long. So setting the maximum to 11
   // bytes will cause it to fail.
   GURL url(test_server_.GetURL("/certs.p7c"));
   std::unique_ptr<CertNetFetcher::Request> request =
-      fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT, 11);
+      fetcher()->FetchCaIssuers(url, CertNetFetcher::DEFAULT, 11);
 
   VerifyFailure(ERR_FILE_TOO_BIG, request.get());
 }
@@ -312,11 +366,11 @@
 TEST_F(CertNetFetcherImplTest, Hang) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url(test_server_.GetURL("/slow/certs.p7c?5"));
   std::unique_ptr<CertNetFetcher::Request> request =
-      fetcher->FetchCaIssuers(url, 10, CertNetFetcher::DEFAULT);
+      fetcher()->FetchCaIssuers(url, 10, CertNetFetcher::DEFAULT);
   VerifyFailure(ERR_TIMED_OUT, request.get());
 }
 
@@ -325,11 +379,11 @@
 TEST_F(CertNetFetcherImplTest, Gzip) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url(test_server_.GetURL("/gzipped_crl"));
   std::unique_ptr<CertNetFetcher::Request> request =
-      StartRequest(fetcher.get(), url);
+      StartRequest(fetcher(), url);
   VerifySuccess("-gzipped_crl-\n", request.get());
 }
 
@@ -337,11 +391,11 @@
 TEST_F(CertNetFetcherImplTest, HttpsNotAllowed) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url("https://foopy/foo.crt");
   std::unique_ptr<CertNetFetcher::Request> request =
-      StartRequest(fetcher.get(), url);
+      StartRequest(fetcher(), url);
   VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request.get());
 
   // No request was created because the URL scheme was unsupported.
@@ -352,12 +406,12 @@
 TEST_F(CertNetFetcherImplTest, RedirectToHttpsNotAllowed) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url(test_server_.GetURL("/redirect_https"));
 
   std::unique_ptr<CertNetFetcher::Request> request =
-      StartRequest(fetcher.get(), url);
+      StartRequest(fetcher(), url);
   VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request.get());
 
   EXPECT_EQ(1, NumCreatedRequests());
@@ -368,11 +422,11 @@
 TEST_F(CertNetFetcherImplTest, CancelHttpsNotAllowed) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url("https://foopy/foo.crt");
   std::unique_ptr<CertNetFetcher::Request> request =
-      StartRequest(fetcher.get(), url);
+      StartRequest(fetcher(), url);
 
   // Cancel the request (May or may not have started yet, as the request is
   // running on another thread).
@@ -384,20 +438,20 @@
 TEST_F(CertNetFetcherImplTest, CancelBeforeRunningMessageLoop) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url1 = test_server_.GetURL("/cert.crt");
   std::unique_ptr<CertNetFetcher::Request> request1 =
-      StartRequest(fetcher.get(), url1);
+      StartRequest(fetcher(), url1);
 
   GURL url2 = test_server_.GetURL("/root.crl");
   std::unique_ptr<CertNetFetcher::Request> request2 =
-      StartRequest(fetcher.get(), url2);
+      StartRequest(fetcher(), url2);
 
   GURL url3 = test_server_.GetURL("/certs.p7c");
 
   std::unique_ptr<CertNetFetcher::Request> request3 =
-      StartRequest(fetcher.get(), url3);
+      StartRequest(fetcher(), url3);
 
   // Cancel the second request.
   request2.reset();
@@ -424,20 +478,20 @@
 TEST_F(CertNetFetcherImplTest, CancelAfterRunningMessageLoop) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url1 = test_server_.GetURL("/cert.crt");
 
   std::unique_ptr<CertNetFetcher::Request> request1 =
-      StartRequest(fetcher.get(), url1);
+      StartRequest(fetcher(), url1);
 
   GURL url2 = test_server_.GetURL("/certs.p7c");
   std::unique_ptr<CertNetFetcher::Request> request2 =
-      StartRequest(fetcher.get(), url2);
+      StartRequest(fetcher(), url2);
 
   GURL url3("ftp://www.not.supported.com/foo");
   std::unique_ptr<CertNetFetcher::Request> request3 =
-      StartRequest(fetcher.get(), url3);
+      StartRequest(fetcher(), url3);
 
   // Wait for the ftp request to complete (it should complete right away since
   // it doesn't even try to connect to the server).
@@ -455,29 +509,29 @@
 TEST_F(CertNetFetcherImplTest, ParallelFetchDuplicates) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url1 = test_server_.GetURL("/cert.crt");
   GURL url2 = test_server_.GetURL("/root.crl");
 
   // Issue 3 requests for url1, and 3 requests for url2
   std::unique_ptr<CertNetFetcher::Request> request1 =
-      StartRequest(fetcher.get(), url1);
+      StartRequest(fetcher(), url1);
 
   std::unique_ptr<CertNetFetcher::Request> request2 =
-      StartRequest(fetcher.get(), url2);
+      StartRequest(fetcher(), url2);
 
   std::unique_ptr<CertNetFetcher::Request> request3 =
-      StartRequest(fetcher.get(), url1);
+      StartRequest(fetcher(), url1);
 
   std::unique_ptr<CertNetFetcher::Request> request4 =
-      StartRequest(fetcher.get(), url2);
+      StartRequest(fetcher(), url2);
 
   std::unique_ptr<CertNetFetcher::Request> request5 =
-      StartRequest(fetcher.get(), url2);
+      StartRequest(fetcher(), url2);
 
   std::unique_ptr<CertNetFetcher::Request> request6 =
-      StartRequest(fetcher.get(), url1);
+      StartRequest(fetcher(), url1);
 
   // Cancel all but one of the requests for url1.
   request1.reset();
@@ -498,19 +552,19 @@
 TEST_F(CertNetFetcherImplTest, CancelThenStart) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
 
   GURL url = test_server_.GetURL("/cert.crt");
 
   std::unique_ptr<CertNetFetcher::Request> request1 =
-      StartRequest(fetcher.get(), url);
+      StartRequest(fetcher(), url);
   request1.reset();
 
   std::unique_ptr<CertNetFetcher::Request> request2 =
-      StartRequest(fetcher.get(), url);
+      StartRequest(fetcher(), url);
 
   std::unique_ptr<CertNetFetcher::Request> request3 =
-      StartRequest(fetcher.get(), url);
+      StartRequest(fetcher(), url);
   request3.reset();
 
   // All but |request2| were canceled.
@@ -521,13 +575,13 @@
 TEST_F(CertNetFetcherImplTest, CancelAll) {
   ASSERT_TRUE(test_server_.Start());
 
-  auto fetcher = CreateFetcher();
+  CreateFetcher();
   std::unique_ptr<CertNetFetcher::Request> request[3];
 
   GURL url = test_server_.GetURL("/cert.crt");
 
   for (size_t i = 0; i < arraysize(request); ++i) {
-    request[i] = StartRequest(fetcher.get(), url);
+    request[i] = StartRequest(fetcher(), url);
   }
 
   // Cancel all the requests.
@@ -537,6 +591,48 @@
   EXPECT_EQ(1, NumCreatedRequests());
 }
 
+// Tests that Requests are signalled for completion even if they are
+// created after the CertNetFetcher has been shutdown.
+TEST_F(CertNetFetcherImplTest, RequestsAfterShutdown) {
+  ASSERT_TRUE(test_server_.Start());
+  CreateFetcher();
+  ShutDownFetcher();
+
+  GURL url = test_server_.GetURL("/cert.crt");
+  std::unique_ptr<CertNetFetcher::Request> request =
+      StartRequest(fetcher(), url);
+  VerifyFailure(ERR_ABORTED, request.get());
+  EXPECT_EQ(0, NumCreatedRequests());
+}
+
+// Tests that Requests are signalled for completion if the fetcher is
+// shutdown and the network thread stopped before the request is
+// started.
+TEST_F(CertNetFetcherImplTest, RequestAfterShutdownAndNetworkThreadStopped) {
+  ASSERT_TRUE(test_server_.Start());
+  CreateFetcher();
+  ShutDownFetcher();
+  ResetState();
+  network_thread_.reset();
+
+  GURL url = test_server_.GetURL("/cert.crt");
+  std::unique_ptr<CertNetFetcher::Request> request =
+      StartRequest(fetcher(), url);
+  VerifyFailure(ERR_ABORTED, request.get());
+}
+
+// Tests that outstanding Requests are cancelled when Shutdown is called.
+TEST_F(CertNetFetcherImplTestWithHangingReadHandler, ShutdownCancelsRequests) {
+  CreateFetcher();
+
+  GURL url = URLRequestHangingReadJob::GetMockHttpUrl();
+  std::unique_ptr<CertNetFetcher::Request> request =
+      StartRequest(fetcher(), url);
+
+  ShutDownFetcher();
+  VerifyFailure(ERR_ABORTED, request.get());
+}
+
 }  // namespace
 
 }  // namespace net
diff --git a/net/test/url_request/url_request_hanging_read_job.cc b/net/test/url_request/url_request_hanging_read_job.cc
index 74c680f241..5223b29 100644
--- a/net/test/url_request/url_request_hanging_read_job.cc
+++ b/net/test/url_request/url_request_hanging_read_job.cc
@@ -92,6 +92,8 @@
 }
 
 void URLRequestHangingReadJob::StartAsync() {
+  if (is_done())
+    return;
   set_expected_content_size(content_length_);
   NotifyHeadersComplete();
 }
diff --git a/net/tools/cert_verify_tool/verify_using_path_builder.cc b/net/tools/cert_verify_tool/verify_using_path_builder.cc
index adaf5fe..6c52e4a 100644
--- a/net/tools/cert_verify_tool/verify_using_path_builder.cc
+++ b/net/tools/cert_verify_tool/verify_using_path_builder.cc
@@ -281,6 +281,9 @@
 
   // Initialize an AIA fetcher, that uses a separate thread for running the
   // networking message loop.
+// TODO(estark): update this code to use the new CertNetFetcher
+// interface that takes a URLRequestContext*.
+#if 0
   base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
   base::Thread thread("network_thread");
   CHECK(thread.StartWithOptions(options));
@@ -290,13 +293,16 @@
       CreateCertNetFetcher(url_request_context_getter.get());
   net::CertIssuerSourceAia aia_cert_issuer_source(cert_net_fetcher.get());
   path_builder.AddCertIssuerSource(&aia_cert_issuer_source);
+#endif
 
   // Run the path builder.
   path_builder.Run();
 
+#if 0
   // Stop the temporary network thread..
   url_request_context_getter->ShutDown();
   thread.Stop();
+#endif
 
   // TODO(crbug.com/634443): Display any errors/warnings associated with path
   //                         building that were not part of a particular
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index d537ee4..e2ae5ef 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -79,8 +79,6 @@
 Bug(none) webexposed/ [ Skip ]
 Bug(none) webmidi/ [ Skip ]
 Bug(none) xmlviewer/ [ Skip ]
-crbug.com/657825 fast/performance/performance-first-paint-timing-observable.html [ Skip ]
-crbug.com/657825 fast/performance/performance-paint-timing-observable.html [ Skip ]
 
 Bug(none) broadcastchannel/blobs.html [ Pass Failure ]
 Bug(none) compositing/3d-cube.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/inspector/components/css-shadow-model.html b/third_party/WebKit/LayoutTests/inspector/components/css-shadow-model.html
index a3b0070..b68303ad 100644
--- a/third_party/WebKit/LayoutTests/inspector/components/css-shadow-model.html
+++ b/third_party/WebKit/LayoutTests/inspector/components/css-shadow-model.html
@@ -2,6 +2,9 @@
 <head>
 <script src="../../http/tests/inspector/inspector-test.js"></script>
 <script>
+var initialize_Test = function() {
+    InspectorTest.preloadModule("inline_editor");
+};
 
 function test()
 {
@@ -88,7 +91,7 @@
 
     function dumpCSSLength(lengthText)
     {
-        var length = Common.CSSLength.parse(lengthText);
+        var length = InlineEditor.CSSLength.parse(lengthText);
         var statusText = length !== null ? "Succeeded: " + length.asCSSText() : "Failed";
         InspectorTest.addResult("\"" + lengthText  + "\", Parsing " + statusText);
     }
@@ -105,7 +108,7 @@
 
     function dumpShadow(shadowText, isBoxShadow)
     {
-        var shadows = isBoxShadow ? Common.CSSShadowModel.parseBoxShadow(shadowText) : Common.CSSShadowModel.parseTextShadow(shadowText);
+        var shadows = isBoxShadow ? InlineEditor.CSSShadowModel.parseBoxShadow(shadowText) : InlineEditor.CSSShadowModel.parseTextShadow(shadowText);
         var output = [];
         for (var i = 0; i < shadows.length; i++)
             output.push(shadows[i].asCSSText());
diff --git a/third_party/WebKit/LayoutTests/inspector/components/geometry.html b/third_party/WebKit/LayoutTests/inspector/components/geometry.html
index 8c4ba73..88145917 100644
--- a/third_party/WebKit/LayoutTests/inspector/components/geometry.html
+++ b/third_party/WebKit/LayoutTests/inspector/components/geometry.html
@@ -9,9 +9,9 @@
             function testVectorLength(next)
             {
                 var testVectors = [
-                    new Common.Geometry.Vector(3, 4, 5),
-                    new Common.Geometry.Vector(-1, 0, -1),
-                    new Common.Geometry.Vector(6, -2, 3)
+                    new UI.Geometry.Vector(3, 4, 5),
+                    new UI.Geometry.Vector(-1, 0, -1),
+                    new UI.Geometry.Vector(6, -2, 3)
                 ];
                 InspectorTest.addResult("Testing vector length");
                 for (var i = 0; i < testVectors.length; ++i)
@@ -23,9 +23,9 @@
             function testVectorNormalize(next)
             {
                 var testVectors = [
-                    new Common.Geometry.Vector(3, 4, 5),
-                    new Common.Geometry.Vector(-1, 0, -1),
-                    new Common.Geometry.Vector(6, -2, 3)
+                    new UI.Geometry.Vector(3, 4, 5),
+                    new UI.Geometry.Vector(-1, 0, -1),
+                    new UI.Geometry.Vector(6, -2, 3)
                 ];
 
                 var eps = 1e-05;
@@ -34,7 +34,7 @@
                     InspectorTest.assertTrue(Math.abs(testVectors[i].length() - 1) <= eps, "Length of normalized vector is not 1")
                 }
 
-                var zeroVector = new Common.Geometry.Vector(0, 0, 0);
+                var zeroVector = new UI.Geometry.Vector(0, 0, 0);
                 zeroVector.normalize();
                 InspectorTest.assertTrue(zeroVector.length() <= eps, "Zero vector after normalization isn't zero vector");
                 next();
@@ -43,19 +43,19 @@
             function testScalarProduct(next)
             {
                 var vectorsU = [
-                    new Common.Geometry.Vector(3, 4, 5),
-                    new Common.Geometry.Vector(-1, 0, -1),
-                    new Common.Geometry.Vector(6, -2, 3)
+                    new UI.Geometry.Vector(3, 4, 5),
+                    new UI.Geometry.Vector(-1, 0, -1),
+                    new UI.Geometry.Vector(6, -2, 3)
                 ];
 
                 var vectorsV = [
-                    new Common.Geometry.Vector(1, 10, -5),
-                    new Common.Geometry.Vector(2, 3, 4),
-                    new Common.Geometry.Vector(0, 0, 0)
+                    new UI.Geometry.Vector(1, 10, -5),
+                    new UI.Geometry.Vector(2, 3, 4),
+                    new UI.Geometry.Vector(0, 0, 0)
                 ];
 
                 for (var i = 0; i < vectorsU.length; ++i)
-                    InspectorTest.addResult("Scalar Product:" + Common.Geometry.scalarProduct(vectorsU[i], vectorsV[i]))
+                    InspectorTest.addResult("Scalar Product:" + UI.Geometry.scalarProduct(vectorsU[i], vectorsV[i]))
 
                 next();
             },
@@ -63,19 +63,19 @@
             function testCrossProduct(next)
             {
                 var vectorsU = [
-                    new Common.Geometry.Vector(3, 4, 5),
-                    new Common.Geometry.Vector(-1, 0, -1),
-                    new Common.Geometry.Vector(6, -2, 3)
+                    new UI.Geometry.Vector(3, 4, 5),
+                    new UI.Geometry.Vector(-1, 0, -1),
+                    new UI.Geometry.Vector(6, -2, 3)
                 ];
 
                 var vectorsV = [
-                    new Common.Geometry.Vector(1, 10, -5),
-                    new Common.Geometry.Vector(2, 3, 4),
-                    new Common.Geometry.Vector(0, 0, 0)
+                    new UI.Geometry.Vector(1, 10, -5),
+                    new UI.Geometry.Vector(2, 3, 4),
+                    new UI.Geometry.Vector(0, 0, 0)
                 ];
 
                 for (var i = 0; i < vectorsU.length; ++i) {
-                    var result = Common.Geometry.crossProduct(vectorsU[i], vectorsV[i]);
+                    var result = UI.Geometry.crossProduct(vectorsU[i], vectorsV[i]);
                     InspectorTest.addResult(String.sprintf("Cross Product: [%.4f, %.4f, %.4f]", result.x, result.y, result.z));
                 }
 
@@ -85,21 +85,21 @@
             function testCalculateAngle(next)
             {
                 var vectorsU = [
-                    new Common.Geometry.Vector(3, 4, 5),
-                    new Common.Geometry.Vector(-1, 0, -1),
-                    new Common.Geometry.Vector(1, 1, 0),
-                    new Common.Geometry.Vector(6, -2, 3),
+                    new UI.Geometry.Vector(3, 4, 5),
+                    new UI.Geometry.Vector(-1, 0, -1),
+                    new UI.Geometry.Vector(1, 1, 0),
+                    new UI.Geometry.Vector(6, -2, 3),
                 ];
 
                 var vectorsV = [
-                    new Common.Geometry.Vector(-3, -4, -5),
-                    new Common.Geometry.Vector(2, 3, 4),
-                    new Common.Geometry.Vector(-1, 1, 0),
-                    new Common.Geometry.Vector(0, 0, 0),
+                    new UI.Geometry.Vector(-3, -4, -5),
+                    new UI.Geometry.Vector(2, 3, 4),
+                    new UI.Geometry.Vector(-1, 1, 0),
+                    new UI.Geometry.Vector(0, 0, 0),
                 ];
 
                 for (var i = 0; i < vectorsU.length; ++i)
-                    InspectorTest.addResult(String.sprintf("Calculate angle: %.4f", Common.Geometry.calculateAngle(vectorsU[i], vectorsV[i])));
+                    InspectorTest.addResult(String.sprintf("Calculate angle: %.4f", UI.Geometry.calculateAngle(vectorsU[i], vectorsV[i])));
 
                 next();
             },
@@ -108,7 +108,7 @@
             {
                 var angles = [Math.PI, Math.PI / 4, Math.PI / 6];
                 for (var i = 0; i < angles.length; ++i)
-                    InspectorTest.addResult(String.sprintf("deg: %.4f", Common.Geometry.radiansToDegrees(angles[i])));
+                    InspectorTest.addResult(String.sprintf("deg: %.4f", UI.Geometry.radiansToDegrees(angles[i])));
 
                 next();
             },
@@ -117,7 +117,7 @@
             {
                 var angles = [-30, 0, 30, 90, 180];
                 for (var i = 0; i < angles.length; ++i)
-                    InspectorTest.addResult(String.sprintf("rad: %.4f", Common.Geometry.degreesToRadians(angles[i])));
+                    InspectorTest.addResult(String.sprintf("rad: %.4f", UI.Geometry.degreesToRadians(angles[i])));
 
                 next();
             },
@@ -133,7 +133,7 @@
                 ];
 
                 for (var i = 0; i < rotationMatrices.length; ++i) {
-                    var angles = Common.Geometry.EulerAngles.fromRotationMatrix(new WebKitCSSMatrix(rotationMatrices[i]));
+                    var angles = UI.Geometry.EulerAngles.fromRotationMatrix(new WebKitCSSMatrix(rotationMatrices[i]));
                     InspectorTest.addResult(String.sprintf("Euler angles: %.4f %.4f %.4f", angles.alpha, angles.beta, angles.gamma));
                 }
                 next();
@@ -142,13 +142,13 @@
             function testEulerAnglesToRotate3DString(next)
             {
                 var angles = [
-                    new Common.Geometry.EulerAngles(0, 0, 0),
-                    new Common.Geometry.EulerAngles(1, 2, 3),
-                    new Common.Geometry.EulerAngles(-1, -2, 3),
-                    new Common.Geometry.EulerAngles(-1, 2, -3),
-                    new Common.Geometry.EulerAngles(0, 1, 2),
-                    new Common.Geometry.EulerAngles(1, 0, 2),
-                    new Common.Geometry.EulerAngles(1, 2, 0)
+                    new UI.Geometry.EulerAngles(0, 0, 0),
+                    new UI.Geometry.EulerAngles(1, 2, 3),
+                    new UI.Geometry.EulerAngles(-1, -2, 3),
+                    new UI.Geometry.EulerAngles(-1, 2, -3),
+                    new UI.Geometry.EulerAngles(0, 1, 2),
+                    new UI.Geometry.EulerAngles(1, 0, 2),
+                    new UI.Geometry.EulerAngles(1, 2, 0)
                 ];
 
                 for (var i = 0; i < angles.length; ++i) {
diff --git a/third_party/WebKit/LayoutTests/inspector/device-mode/device-mode-responsive.html b/third_party/WebKit/LayoutTests/inspector/device-mode/device-mode-responsive.html
index ab950bd..ceed2a9 100644
--- a/third_party/WebKit/LayoutTests/inspector/device-mode/device-mode-responsive.html
+++ b/third_party/WebKit/LayoutTests/inspector/device-mode/device-mode-responsive.html
@@ -11,7 +11,7 @@
     var view = new Emulation.DeviceModeView();
     var toolbar = view._toolbar;
     var model = view._model;
-    var viewportSize = new Size(320, 480);
+    var viewportSize = new UI.Size(320, 480);
     model.setAvailableSize(viewportSize, viewportSize);
 
     InspectorTest.addResult("\nSetting device mode to responsive mode with viewport of size: " + JSON.stringify(viewportSize));
diff --git a/third_party/WebKit/LayoutTests/inspector/device-mode/device-mode-switching-devices.html b/third_party/WebKit/LayoutTests/inspector/device-mode/device-mode-switching-devices.html
index caad2e0..f057e33 100644
--- a/third_party/WebKit/LayoutTests/inspector/device-mode/device-mode-switching-devices.html
+++ b/third_party/WebKit/LayoutTests/inspector/device-mode/device-mode-switching-devices.html
@@ -11,7 +11,7 @@
     var view = new Emulation.DeviceModeView();
     var toolbar = view._toolbar;
     var model = view._model;
-    var viewportSize = new Size(800, 600);
+    var viewportSize = new UI.Size(800, 600);
     model.setAvailableSize(viewportSize, viewportSize);
 
     InspectorTest.addResult("\nTest that devices remember their scale.");
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/bezier-swatch-position.html b/third_party/WebKit/LayoutTests/inspector/sources/bezier-swatch-position.html
index 5c7a097..319d771 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/bezier-swatch-position.html
+++ b/third_party/WebKit/LayoutTests/inspector/sources/bezier-swatch-position.html
@@ -21,7 +21,7 @@
             {
                 var swatch = sourceFrame.textEditor._codeMirrorElement.querySelector("span[is=bezier-swatch]");
                 swatch.shadowRoot.querySelector(".bezier-swatch-icon").click();
-                sourceFrame._bezierEditor.setBezier(Common.Geometry.CubicBezier.parse("linear"));
+                sourceFrame._bezierEditor.setBezier(UI.Geometry.CubicBezier.parse("linear"));
                 sourceFrame._bezierEditor._onchange();
                 sourceFrame._swatchPopoverHelper.hide(true)
                 InspectorTest.dumpSwatchPositions(sourceFrame, Sources.CSSSourceFrame.SwatchBookmark);
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp
index 8a50f5e..d3ece36 100644
--- a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp
@@ -84,16 +84,12 @@
 unsigned DOMWrapperWorld::isolatedWorldCount = 0;
 
 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::create(v8::Isolate* isolate,
-                                                    int worldId,
-                                                    int extensionGroup) {
-  return adoptRef(new DOMWrapperWorld(isolate, worldId, extensionGroup));
+                                                    int worldId) {
+  return adoptRef(new DOMWrapperWorld(isolate, worldId));
 }
 
-DOMWrapperWorld::DOMWrapperWorld(v8::Isolate* isolate,
-                                 int worldId,
-                                 int extensionGroup)
+DOMWrapperWorld::DOMWrapperWorld(v8::Isolate* isolate, int worldId)
     : m_worldId(worldId),
-      m_extensionGroup(extensionGroup),
       m_domDataStore(
           WTF::wrapUnique(new DOMDataStore(isolate, isMainWorld()))) {}
 
@@ -101,17 +97,15 @@
   ASSERT(isMainThread());
   DEFINE_STATIC_REF(
       DOMWrapperWorld, cachedMainWorld,
-      (DOMWrapperWorld::create(v8::Isolate::GetCurrent(), MainWorldId,
-                               mainWorldExtensionGroup)));
+      (DOMWrapperWorld::create(v8::Isolate::GetCurrent(), MainWorldId)));
   return *cachedMainWorld;
 }
 
 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::fromWorldId(v8::Isolate* isolate,
-                                                         int worldId,
-                                                         int extensionGroup) {
+                                                         int worldId) {
   if (worldId == MainWorldId)
     return &mainWorld();
-  return ensureIsolatedWorld(isolate, worldId, extensionGroup);
+  return ensureIsolatedWorld(isolate, worldId);
 }
 
 typedef HashMap<int, DOMWrapperWorld*> WorldMap;
@@ -207,8 +201,7 @@
 
 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::ensureIsolatedWorld(
     v8::Isolate* isolate,
-    int worldId,
-    int extensionGroup) {
+    int worldId) {
   ASSERT(isIsolatedWorldId(worldId));
 
   WorldMap& map = isolatedWorldMap();
@@ -216,11 +209,10 @@
   RefPtr<DOMWrapperWorld> world = result.storedValue->value;
   if (world) {
     ASSERT(world->worldId() == worldId);
-    ASSERT(world->extensionGroup() == extensionGroup);
     return world.release();
   }
 
-  world = DOMWrapperWorld::create(isolate, worldId, extensionGroup);
+  world = DOMWrapperWorld::create(isolate, worldId);
   result.storedValue->value = world.get();
   isolatedWorldCount++;
   return world.release();
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h
index fce2a83..bb3fd0b 100644
--- a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h
+++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h
@@ -59,14 +59,10 @@
 // This class represent a collection of DOM wrappers for a specific world.
 class CORE_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
  public:
-  static PassRefPtr<DOMWrapperWorld> create(v8::Isolate*,
-                                            int worldId = -1,
-                                            int extensionGroup = -1);
+  static PassRefPtr<DOMWrapperWorld> create(v8::Isolate*, int worldId = -1);
 
-  static const int mainWorldExtensionGroup = 0;
   static PassRefPtr<DOMWrapperWorld> ensureIsolatedWorld(v8::Isolate*,
-                                                         int worldId,
-                                                         int extensionGroup);
+                                                         int worldId);
   ~DOMWrapperWorld();
   void dispose();
 
@@ -88,9 +84,7 @@
   }
 
   static DOMWrapperWorld& mainWorld();
-  static PassRefPtr<DOMWrapperWorld> fromWorldId(v8::Isolate*,
-                                                 int worldId,
-                                                 int extensionGroup);
+  static PassRefPtr<DOMWrapperWorld> fromWorldId(v8::Isolate*, int worldId);
 
   static void setIsolatedWorldHumanReadableName(int worldID, const String&);
   String isolatedWorldHumanReadableName();
@@ -121,7 +115,6 @@
   }
 
   int worldId() const { return m_worldId; }
-  int extensionGroup() const { return m_extensionGroup; }
   DOMDataStore& domDataStore() const { return *m_domDataStore; }
 
  public:
@@ -129,7 +122,7 @@
   void registerDOMObjectHolder(v8::Isolate*, T*, v8::Local<v8::Value>);
 
  private:
-  DOMWrapperWorld(v8::Isolate*, int worldId, int extensionGroup);
+  DOMWrapperWorld(v8::Isolate*, int worldId);
 
   static void weakCallbackForDOMObjectHolder(
       const v8::WeakCallbackInfo<DOMObjectHolderBase>&);
@@ -139,7 +132,6 @@
   static unsigned isolatedWorldCount;
 
   const int m_worldId;
-  const int m_extensionGroup;
   std::unique_ptr<DOMDataStore> m_domDataStore;
   HashSet<std::unique_ptr<DOMObjectHolderBase>> m_domObjectHolders;
 };
diff --git a/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp b/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp
index a0d7e39..ae873c5 100644
--- a/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp
@@ -117,8 +117,8 @@
 
   MainThreadDebugger::instance()->contextCreated(m_scriptState.get(), frame(),
                                                  origin);
-  frame()->loader().client()->didCreateScriptContext(
-      context, m_world->extensionGroup(), m_world->worldId());
+  frame()->loader().client()->didCreateScriptContext(context,
+                                                     m_world->worldId());
   // If conditional features for window have been queued before the V8 context
   // was ready, then inject them into the context now
   if (m_world->isMainWorld()) {
@@ -139,21 +139,13 @@
       V8Window::domTemplate(isolate(), *m_world)->InstanceTemplate();
   CHECK(!globalTemplate.IsEmpty());
 
-  // FIXME: It's not clear what the right thing to do for remote frames is.
-  // The extensions registered don't generally seem to make sense for remote
-  // frames, so skip it for now.
   Vector<const char*> extensionNames;
   // Dynamically tell v8 about our extensions now.
-  const V8Extensions& extensions = ScriptController::registeredExtensions();
-  extensionNames.reserveInitialCapacity(extensions.size());
-  int extensionGroup = m_world->extensionGroup();
-  int worldId = m_world->worldId();
-  for (const auto* extension : extensions) {
-    if (!frame()->loader().client()->allowScriptExtension(
-            extension->name(), extensionGroup, worldId))
-      continue;
-
-    extensionNames.push_back(extension->name());
+  if (frame()->loader().client()->allowScriptExtensions()) {
+    const V8Extensions& extensions = ScriptController::registeredExtensions();
+    extensionNames.reserveInitialCapacity(extensions.size());
+    for (const auto* extension : extensions)
+      extensionNames.push_back(extension->name());
   }
   v8::ExtensionConfiguration extensionConfiguration(extensionNames.size(),
                                                     extensionNames.data());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
index 1f94c6f..6cddc16 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
@@ -435,12 +435,11 @@
 void ScriptController::executeScriptInIsolatedWorld(
     int worldID,
     const HeapVector<ScriptSourceCode>& sources,
-    int extensionGroup,
     Vector<v8::Local<v8::Value>>* results) {
   ASSERT(worldID > 0);
 
   RefPtr<DOMWrapperWorld> world =
-      DOMWrapperWorld::ensureIsolatedWorld(isolate(), worldID, extensionGroup);
+      DOMWrapperWorld::ensureIsolatedWorld(isolate(), worldID);
   LocalWindowProxy* isolatedWorldWindowProxy = windowProxy(*world);
   ScriptState* scriptState = isolatedWorldWindowProxy->getScriptState();
   if (!scriptState->contextIsValid())
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.h b/third_party/WebKit/Source/bindings/core/v8/ScriptController.h
index 747bea0..9b1e5a0 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.h
@@ -108,11 +108,9 @@
   // If an isolated world with the specified ID already exists, it is reused.
   // Otherwise, a new world is created.
   //
-  // FIXME: Get rid of extensionGroup here.
   // FIXME: We don't want to support multiple scripts.
   void executeScriptInIsolatedWorld(int worldID,
                                     const HeapVector<ScriptSourceCode>& sources,
-                                    int extensionGroup,
                                     Vector<v8::Local<v8::Value>>* results);
 
   // Returns true if argument is a JavaScript URL.
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
index e4caee2..0ede386 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
@@ -101,7 +101,7 @@
     v8::HandleScope handleScope(isolate());
     m_otherScriptState = ScriptStateForTesting::create(
         v8::Context::New(isolate()),
-        DOMWrapperWorld::ensureIsolatedWorld(isolate(), 1, -1));
+        DOMWrapperWorld::ensureIsolatedWorld(isolate(), 1));
   }
 
   virtual ~ScriptPromisePropertyTestBase() { destroyContext(); }
diff --git a/third_party/WebKit/Source/bindings/core/v8/ToV8.cpp b/third_party/WebKit/Source/bindings/core/v8/ToV8.cpp
index 3d70c56..4288949 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ToV8.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ToV8.cpp
@@ -5,11 +5,9 @@
 #include "bindings/core/v8/ToV8.h"
 
 #include "bindings/core/v8/WindowProxy.h"
-#include "bindings/core/v8/WorkerOrWorkletScriptController.h"
 #include "core/events/EventTarget.h"
 #include "core/frame/DOMWindow.h"
 #include "core/frame/Frame.h"
-#include "core/workers/WorkerOrWorkletGlobalScope.h"
 
 namespace blink {
 
@@ -42,22 +40,4 @@
   return ToV8(static_cast<ScriptWrappable*>(impl), creationContext, isolate);
 }
 
-v8::Local<v8::Value> ToV8(WorkerOrWorkletGlobalScope* impl,
-                          v8::Local<v8::Object> creationContext,
-                          v8::Isolate* isolate) {
-  // Notice that we explicitly ignore creationContext because the
-  // WorkerOrWorkletGlobalScope has its own creationContext.
-
-  if (UNLIKELY(!impl))
-    return v8::Null(isolate);
-
-  WorkerOrWorkletScriptController* scriptController = impl->scriptController();
-  if (!scriptController)
-    return v8::Null(isolate);
-
-  v8::Local<v8::Object> global = scriptController->context()->Global();
-  ASSERT(!global.IsEmpty());
-  return global;
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ToV8.h b/third_party/WebKit/Source/bindings/core/v8/ToV8.h
index 0e2086d..2495d769 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ToV8.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ToV8.h
@@ -25,7 +25,6 @@
 class DOMWindow;
 class Dictionary;
 class EventTarget;
-class WorkerOrWorkletGlobalScope;
 
 // ScriptWrappable
 
@@ -57,7 +56,7 @@
   return wrapper;
 }
 
-// Special versions for DOMWindow, WorkerOrWorkletGlobalScope and EventTarget
+// Special versions for DOMWindow and EventTarget
 
 CORE_EXPORT v8::Local<v8::Value> ToV8(DOMWindow*,
                                       v8::Local<v8::Object> creationContext,
@@ -65,9 +64,6 @@
 CORE_EXPORT v8::Local<v8::Value> ToV8(EventTarget*,
                                       v8::Local<v8::Object> creationContext,
                                       v8::Isolate*);
-v8::Local<v8::Value> ToV8(WorkerOrWorkletGlobalScope*,
-                          v8::Local<v8::Object> creationContext,
-                          v8::Isolate*);
 
 // Primitives
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Binding.h b/third_party/WebKit/Source/bindings/core/v8/V8Binding.h
index 6cd470f..00392a5 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Binding.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Binding.h
@@ -64,8 +64,6 @@
 class LocalDOMWindow;
 class LocalFrame;
 class NodeFilter;
-class WorkerGlobalScope;
-class WorkerOrWorkletGlobalScope;
 class XPathNSResolver;
 
 template <typename T>
@@ -204,7 +202,7 @@
   v8SetReturnValue(callbackInfo, wrapper);
 }
 
-// Special versions for DOMWindow, WorkerGlobalScope and EventTarget
+// Special versions for DOMWindow and EventTarget
 
 template <typename CallbackInfo>
 inline void v8SetReturnValue(const CallbackInfo& callbackInfo,
@@ -220,14 +218,6 @@
                                       callbackInfo.GetIsolate()));
 }
 
-template <typename CallbackInfo>
-inline void v8SetReturnValue(const CallbackInfo& callbackInfo,
-                             WorkerGlobalScope* impl) {
-  v8SetReturnValue(callbackInfo,
-                   ToV8((WorkerOrWorkletGlobalScope*)impl,
-                        callbackInfo.Holder(), callbackInfo.GetIsolate()));
-}
-
 template <typename CallbackInfo, typename T>
 inline void v8SetReturnValue(const CallbackInfo& callbackInfo,
                              PassRefPtr<T> impl) {
@@ -274,7 +264,7 @@
   v8SetReturnValueForMainWorld(callbackInfo, ScriptWrappable::fromNode(impl));
 }
 
-// Special versions for DOMWindow, WorkerGlobalScope and EventTarget
+// Special versions for DOMWindow and EventTarget
 
 template <typename CallbackInfo>
 inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo,
@@ -290,14 +280,6 @@
                                       callbackInfo.GetIsolate()));
 }
 
-template <typename CallbackInfo>
-inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo,
-                                         WorkerGlobalScope* impl) {
-  v8SetReturnValue(callbackInfo,
-                   ToV8((WorkerOrWorkletGlobalScope*)impl,
-                        callbackInfo.Holder(), callbackInfo.GetIsolate()));
-}
-
 template <typename CallbackInfo, typename T>
 inline void v8SetReturnValueForMainWorld(const CallbackInfo& callbackInfo,
                                          PassRefPtr<T> impl) {
@@ -336,7 +318,7 @@
   v8SetReturnValue(callbackInfo, wrapper);
 }
 
-// Special versions for DOMWindow, WorkerGlobalScope and EventTarget
+// Special versions for DOMWindow and EventTarget
 
 template <typename CallbackInfo>
 inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo,
@@ -354,15 +336,6 @@
                                       callbackInfo.GetIsolate()));
 }
 
-template <typename CallbackInfo>
-inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo,
-                                 WorkerGlobalScope* impl,
-                                 const ScriptWrappable*) {
-  v8SetReturnValue(callbackInfo,
-                   ToV8((WorkerOrWorkletGlobalScope*)impl,
-                        callbackInfo.Holder(), callbackInfo.GetIsolate()));
-}
-
 template <typename CallbackInfo, typename T, typename Wrappable>
 inline void v8SetReturnValueFast(const CallbackInfo& callbackInfo,
                                  PassRefPtr<T> impl,
diff --git a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
index 588ab45..584f5181 100644
--- a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
@@ -180,16 +180,43 @@
 
   ScriptState::Scope scope(m_scriptState.get());
 
+  // Associate the global proxy object, the global object and the worker
+  // instance (C++ object) as follows.
+  //
+  //   global proxy object <====> worker or worklet instance
+  //                               ^
+  //                               |
+  //   global object       --------+
+  //
+  // Per HTML spec, there is no corresponding object for workers to WindowProxy.
+  // However, V8 always creates the global proxy object, we associate these
+  // objects in the same manner as WindowProxy and Window.
+  //
+  // a) worker or worklet instance --> global proxy object
+  // As we shouldn't expose the global object to author scripts, we map the
+  // worker or worklet instance to the global proxy object.
+  // b) global proxy object --> worker or worklet instance
+  // Blink's callback functions are called by V8 with the global proxy object,
+  // we need to map the global proxy object to the worker or worklet instance.
+  // c) global object --> worker or worklet instance
+  // The global proxy object is NOT considered as a wrapper object of the
+  // worker or worklet instance because it's not an instance of
+  // v8::FunctionTemplate of worker or worklet, especially note that
+  // v8::Object::FindInstanceInPrototypeChain skips the global proxy object.
+  // Thus we need to map the global object to the worker or worklet instance.
+
   // The global proxy object.  Note this is not the global object.
   v8::Local<v8::Object> globalProxy = context->Global();
-  V8DOMWrapper::setNativeInfo(m_isolate, globalProxy, wrapperTypeInfo,
-                              scriptWrappable);
+  v8::Local<v8::Object> associatedWrapper =
+      V8DOMWrapper::associateObjectWithWrapper(
+          m_isolate, scriptWrappable, wrapperTypeInfo, globalProxy);
+  CHECK(globalProxy == associatedWrapper);
 
   // The global object, aka worker/worklet wrapper object.
   v8::Local<v8::Object> globalObject =
       globalProxy->GetPrototype().As<v8::Object>();
-  globalObject = V8DOMWrapper::associateObjectWithWrapper(
-      m_isolate, scriptWrappable, wrapperTypeInfo, globalObject);
+  V8DOMWrapper::setNativeInfo(m_isolate, globalObject, wrapperTypeInfo,
+                              scriptWrappable);
 
   // All interfaces must be registered to V8PerContextData.
   // So we explicitly call constructorForType for the global object.
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
index 2baa7e91..9d67471 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -928,42 +928,37 @@
       initial = true;
   }
 
-  DCHECK(initial ^ inherit);
-
+  state.style()->removeVariable(name, isInheritedProperty);
   if (initial) {
-    if (isInheritedProperty)
-      state.style()->removeInheritedVariable(name);
-    else
-      state.style()->removeNonInheritedVariable(name);
     return;
   }
 
-  if (isInheritedProperty) {
-    state.style()->removeInheritedVariable(name);
-    StyleInheritedVariables* parentVariables =
-        state.parentStyle()->inheritedVariables();
-    if (!parentVariables)
-      return;
-    CSSVariableData* parentValue = parentVariables->getVariable(name);
+  DCHECK(inherit);
+  CSSVariableData* parentValue =
+      state.parentStyle()->getVariable(name, isInheritedProperty);
+  const CSSValue* parentCSSValue =
+      registration && parentValue
+          ? state.parentStyle()->getRegisteredVariable(name,
+                                                       isInheritedProperty)
+          : nullptr;
+
+  if (!isInheritedProperty) {
+    DCHECK(registration);
     if (parentValue) {
-      if (!registration)
-        state.style()->setResolvedUnregisteredVariable(name, parentValue);
-      else
-        state.style()->setResolvedInheritedVariable(
-            name, parentValue, parentVariables->registeredVariable(name));
+      state.style()->setResolvedNonInheritedVariable(name, parentValue,
+                                                     parentCSSValue);
     }
     return;
   }
 
-  state.style()->removeNonInheritedVariable(name);
-  StyleNonInheritedVariables* parentVariables =
-      state.parentStyle()->nonInheritedVariables();
-  if (!parentVariables)
-    return;
-  CSSVariableData* parentValue = parentVariables->getVariable(name);
-  if (parentValue)
-    state.style()->setResolvedNonInheritedVariable(
-        name, parentValue, parentVariables->registeredVariable(name));
+  if (parentValue) {
+    if (!registration) {
+      state.style()->setResolvedUnregisteredVariable(name, parentValue);
+    } else {
+      state.style()->setResolvedInheritedVariable(name, parentValue,
+                                                  parentCSSValue);
+    }
+  }
 }
 
 void StyleBuilderFunctions::applyInheritCSSPropertyBaselineShift(
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
index 70361e9..a1e899c 100644
--- a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
+++ b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
@@ -114,6 +114,8 @@
   ResourceLoaderOptions resourceLoaderOptions;
   resourceLoaderOptions.allowCredentials = AllowStoredCredentials;
 
+  // TODO(yhirano): Remove this CHECK once https://crbug.com/667254 is fixed.
+  CHECK(!m_loader);
   if (m_client) {
     DCHECK(!m_loader);
     m_loader = ThreadableLoader::create(*executionContext, this, options,
diff --git a/third_party/WebKit/Source/core/frame/BarProp.cpp b/third_party/WebKit/Source/core/frame/BarProp.cpp
index 6a76bba6..e403c7c 100644
--- a/third_party/WebKit/Source/core/frame/BarProp.cpp
+++ b/third_party/WebKit/Source/core/frame/BarProp.cpp
@@ -35,10 +35,10 @@
 namespace blink {
 
 BarProp::BarProp(LocalFrame* frame, Type type)
-    : ContextClient(frame), m_type(type) {}
+    : DOMWindowClient(frame), m_type(type) {}
 
 DEFINE_TRACE(BarProp) {
-  ContextClient::trace(visitor);
+  DOMWindowClient::trace(visitor);
 }
 
 bool BarProp::visible() const {
diff --git a/third_party/WebKit/Source/core/frame/BarProp.h b/third_party/WebKit/Source/core/frame/BarProp.h
index 983eac1..d4b3dae 100644
--- a/third_party/WebKit/Source/core/frame/BarProp.h
+++ b/third_party/WebKit/Source/core/frame/BarProp.h
@@ -39,7 +39,7 @@
 
 class BarProp final : public GarbageCollected<BarProp>,
                       public ScriptWrappable,
-                      public ContextClient {
+                      public DOMWindowClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(BarProp);
 
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.cpp b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
index 3ce520e..c5f9123 100644
--- a/third_party/WebKit/Source/core/frame/DOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
@@ -34,9 +34,12 @@
 
 namespace blink {
 
-DOMWindow::DOMWindow() : m_windowIsClosing(false) {}
+DOMWindow::DOMWindow(Frame& frame) : m_frame(frame), m_windowIsClosing(false) {}
 
-DOMWindow::~DOMWindow() {}
+DOMWindow::~DOMWindow() {
+  // The frame must be disconnected before finalization.
+  DCHECK(!m_frame);
+}
 
 v8::Local<v8::Object> DOMWindow::wrap(v8::Isolate*,
                                       v8::Local<v8::Object> creationContext) {
@@ -432,6 +435,7 @@
 }
 
 DEFINE_TRACE(DOMWindow) {
+  visitor->trace(m_frame);
   visitor->trace(m_location);
   EventTargetWithInlineData::trace(visitor);
 }
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.h b/third_party/WebKit/Source/core/frame/DOMWindow.h
index 1b74b487..44f155c 100644
--- a/third_party/WebKit/Source/core/frame/DOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/DOMWindow.h
@@ -9,9 +9,10 @@
 #include "core/CoreExport.h"
 #include "core/events/EventTarget.h"
 #include "core/frame/DOMWindowBase64.h"
+#include "core/frame/Frame.h"
 #include "platform/heap/Handle.h"
 #include "platform/scroll/ScrollableArea.h"
-
+#include "wtf/Assertions.h"
 #include "wtf/Forward.h"
 
 namespace blink {
@@ -26,7 +27,6 @@
 class Document;
 class Element;
 class External;
-class Frame;
 class FrameRequestCallback;
 class History;
 class IdleRequestCallback;
@@ -49,14 +49,20 @@
  public:
   ~DOMWindow() override;
 
+  Frame* frame() const {
+    // If the DOMWindow still has a frame reference, that frame must point
+    // back to this DOMWindow: otherwise, it's easy to get into a situation
+    // where script execution leaks between different DOMWindows.
+    SECURITY_DCHECK(!m_frame || m_frame->domWindow() == this);
+    return m_frame;
+  }
+
   // GarbageCollectedFinalized overrides:
   DECLARE_VIRTUAL_TRACE();
 
   virtual bool isLocalDOMWindow() const = 0;
   virtual bool isRemoteDOMWindow() const = 0;
 
-  virtual Frame* frame() const = 0;
-
   // ScriptWrappable overrides:
   v8::Local<v8::Object> wrap(v8::Isolate*,
                              v8::Local<v8::Object> creationContext) final;
@@ -255,12 +261,18 @@
   DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange);
 
  protected:
-  DOMWindow();
+  explicit DOMWindow(Frame&);
 
   virtual void schedulePostMessage(MessageEvent*,
                                    PassRefPtr<SecurityOrigin> target,
                                    Document* source) = 0;
 
+  void disconnectFromFrame() { m_frame = nullptr; }
+
+ private:
+  Member<Frame> m_frame;
+  mutable Member<Location> m_location;
+
   // Set to true when close() has been called. Needed for
   // |window.closed| determinism; having it return 'true'
   // only after the layout widget's deferred window close
@@ -268,8 +280,6 @@
   // implementation details to scripts.
   bool m_windowIsClosing;
 
- private:
-  mutable Member<Location> m_location;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index d257543..19b5a0a 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -94,6 +94,7 @@
 #include "core/page/scrolling/TopDocumentRootScrollerController.h"
 #include "core/paint/FramePainter.h"
 #include "core/paint/PaintLayer.h"
+#include "core/paint/PaintTiming.h"
 #include "core/paint/PrePaintTreeWalk.h"
 #include "core/plugins/PluginView.h"
 #include "core/style/ComputedStyle.h"
@@ -3003,6 +3004,14 @@
   });
 }
 
+void FrameView::notifyPaint(const PaintController& paintController) const {
+  DCHECK(m_frame->document());
+  PaintTiming::from(*m_frame->document())
+      .notifyPaint(paintController.firstPainted(),
+                   paintController.textPainted(),
+                   paintController.imagePainted());
+}
+
 void FrameView::paintTree() {
   TRACE_EVENT0("blink", "FrameView::paintTree");
   SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Blink.Paint.UpdateTime");
@@ -3021,6 +3030,7 @@
       GraphicsContext graphicsContext(*m_paintController);
       paint(graphicsContext, CullRect(LayoutRect::infiniteIntRect()));
       m_paintController->commitNewDisplayItems(LayoutSize());
+      notifyPaint(*m_paintController);
     }
   } else {
     // A null graphics layer can occur for painting of SVG images that are not
@@ -3059,8 +3069,10 @@
 }
 
 void FrameView::paintGraphicsLayerRecursively(GraphicsLayer* graphicsLayer) {
-  if (graphicsLayer->drawsContent())
+  if (graphicsLayer->drawsContent()) {
     graphicsLayer->paint(nullptr);
+    notifyPaint(graphicsLayer->getPaintController());
+  }
 
   if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h
index d837f607..fb210b8 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -869,6 +869,8 @@
   void updateStyleAndLayoutIfNeededRecursiveInternal();
   void invalidateTreeIfNeededRecursiveInternal();
 
+  // TODO(wangxianzhu): Remove the parameter and use m_paintController for SPv2.
+  void notifyPaint(const PaintController&) const;
   void pushPaintArtifactToCompositor();
 
   void reset();
diff --git a/third_party/WebKit/Source/core/frame/History.cpp b/third_party/WebKit/Source/core/frame/History.cpp
index 5e73052..a1dd7e7bf 100644
--- a/third_party/WebKit/Source/core/frame/History.cpp
+++ b/third_party/WebKit/Source/core/frame/History.cpp
@@ -57,10 +57,10 @@
 }  // namespace
 
 History::History(LocalFrame* frame)
-    : ContextClient(frame), m_lastStateObjectRequested(nullptr) {}
+    : DOMWindowClient(frame), m_lastStateObjectRequested(nullptr) {}
 
 DEFINE_TRACE(History) {
-  ContextClient::trace(visitor);
+  DOMWindowClient::trace(visitor);
 }
 
 unsigned History::length() const {
diff --git a/third_party/WebKit/Source/core/frame/History.h b/third_party/WebKit/Source/core/frame/History.h
index 1b3db702..4d3ab7d 100644
--- a/third_party/WebKit/Source/core/frame/History.h
+++ b/third_party/WebKit/Source/core/frame/History.h
@@ -45,7 +45,7 @@
 // This class corresponds to the History interface.
 class CORE_EXPORT History final : public GarbageCollectedFinalized<History>,
                                   public ScriptWrappable,
-                                  public ContextClient {
+                                  public DOMWindowClient {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(History);
 
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index 497f343..8192bcb 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -273,7 +273,7 @@
 }
 
 LocalDOMWindow::LocalDOMWindow(LocalFrame& frame)
-    : m_frame(&frame),
+    : DOMWindow(frame),
       m_visualViewport(DOMVisualViewport::create(this)),
       m_unusedPreloadsTimer(
           TaskRunnerHelper::get(TaskType::UnspecedTimer, &frame),
@@ -485,7 +485,7 @@
   resetLocation();
   m_properties.clear();
   removeAllEventListeners();
-  m_frame = nullptr;
+  disconnectFromFrame();
 }
 
 void LocalDOMWindow::registerProperty(DOMWindowProperty* property) {
@@ -1608,7 +1608,6 @@
 }
 
 DEFINE_TRACE(LocalDOMWindow) {
-  visitor->trace(m_frame);
   visitor->trace(m_document);
   visitor->trace(m_properties);
   visitor->trace(m_screen);
@@ -1636,12 +1635,4 @@
   DOMWindow::traceWrappers(visitor);
 }
 
-LocalFrame* LocalDOMWindow::frame() const {
-  // If the LocalDOMWindow still has a frame reference, that frame must point
-  // back to this LocalDOMWindow: otherwise, it's easy to get into a situation
-  // where script execution leaks between different LocalDOMWindows.
-  SECURITY_DCHECK(!m_frame || m_frame->domWindow() == this);
-  return m_frame;
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
index 337297b..ad9a4cb 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
@@ -82,6 +82,8 @@
 
   ~LocalDOMWindow() override;
 
+  LocalFrame* frame() const { return toLocalFrame(DOMWindow::frame()); }
+
   DECLARE_VIRTUAL_TRACE();
   DECLARE_VIRTUAL_TRACE_WRAPPERS();
 
@@ -95,7 +97,6 @@
   LocalDOMWindow* toLocalDOMWindow() override;
 
   // DOMWindow overrides:
-  LocalFrame* frame() const override;
   Screen* screen() const override;
   History* history() const override;
   BarProp* locationbar() const override;
@@ -260,7 +261,6 @@
 
   void willDetachFrameHost();
 
-  Member<LocalFrame> m_frame;
   Member<Document> m_document;
   Member<DOMVisualViewport> m_visualViewport;
   TaskRunnerTimer<LocalDOMWindow> m_unusedPreloadsTimer;
diff --git a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp
index 52c42c2..706ee2a 100644
--- a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp
@@ -18,14 +18,9 @@
 }
 
 DEFINE_TRACE(RemoteDOMWindow) {
-  visitor->trace(m_frame);
   DOMWindow::trace(visitor);
 }
 
-RemoteFrame* RemoteDOMWindow::frame() const {
-  return m_frame.get();
-}
-
 Screen* RemoteDOMWindow::screen() const {
   ASSERT_NOT_REACHED();
   return nullptr;
@@ -290,16 +285,16 @@
   return nullptr;
 }
 
-RemoteDOMWindow::RemoteDOMWindow(RemoteFrame& frame) : m_frame(&frame) {}
+RemoteDOMWindow::RemoteDOMWindow(RemoteFrame& frame) : DOMWindow(frame) {}
 
 void RemoteDOMWindow::frameDetached() {
-  m_frame = nullptr;
+  disconnectFromFrame();
 }
 
 void RemoteDOMWindow::schedulePostMessage(MessageEvent* event,
                                           PassRefPtr<SecurityOrigin> target,
                                           Document* source) {
-  m_frame->client()->forwardPostMessage(event, std::move(target),
+  frame()->client()->forwardPostMessage(event, std::move(target),
                                         source->frame());
 }
 
diff --git a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h
index 13c6538..e1e8241 100644
--- a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h
@@ -17,12 +17,13 @@
     return new RemoteDOMWindow(frame);
   }
 
+  RemoteFrame* frame() const { return toRemoteFrame(DOMWindow::frame()); }
+
   // EventTarget overrides:
   ExecutionContext* getExecutionContext() const override;
 
   // DOMWindow overrides:
   DECLARE_VIRTUAL_TRACE();
-  RemoteFrame* frame() const override;
   Screen* screen() const override;
   History* history() const override;
   BarProp* locationbar() const override;
@@ -106,8 +107,6 @@
   // already RemoteDOMWindow.
   bool isLocalDOMWindow() const override { return false; }
   bool isRemoteDOMWindow() const override { return true; }
-
-  Member<RemoteFrame> m_frame;
 };
 
 DEFINE_TYPE_CASTS(RemoteDOMWindow,
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrame.cpp b/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
index c9c83df3..652f833 100644
--- a/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
@@ -103,6 +103,12 @@
   client()->willBeDetached();
   m_windowProxyManager->clearForClose();
   setView(nullptr);
+  // ... the RemoteDOMWindow will need to be informed of detachment,
+  // as otherwise it will keep a strong reference back to this RemoteFrame.
+  // That combined with wrappers (owned and kept alive by RemoteFrame) keeping
+  // persistent strong references to RemoteDOMWindow will prevent the GCing
+  // of all these objects. Break the cycle by notifying of detachment.
+  toRemoteDOMWindow(m_domWindow)->frameDetached();
   if (m_webLayer)
     setWebLayer(nullptr);
   Frame::detach(type);
@@ -144,14 +150,6 @@
   // Oilpan: as RemoteFrameView performs no finalization actions,
   // no explicit dispose() of it needed here. (cf. FrameView::dispose().)
   m_view = view;
-
-  // ... the RemoteDOMWindow will need to be informed of detachment,
-  // as otherwise it will keep a strong reference back to this RemoteFrame.
-  // That combined with wrappers (owned and kept alive by RemoteFrame) keeping
-  // persistent strong references to RemoteDOMWindow will prevent the GCing
-  // of all these objects. Break the cycle by notifying of detachment.
-  if (!m_view)
-    toRemoteDOMWindow(m_domWindow)->frameDetached();
 }
 
 void RemoteFrame::createView() {
diff --git a/third_party/WebKit/Source/core/frame/Screen.cpp b/third_party/WebKit/Source/core/frame/Screen.cpp
index c945d6c..0abf20f 100644
--- a/third_party/WebKit/Source/core/frame/Screen.cpp
+++ b/third_party/WebKit/Source/core/frame/Screen.cpp
@@ -38,7 +38,7 @@
 
 namespace blink {
 
-Screen::Screen(LocalFrame* frame) : ContextClient(frame) {}
+Screen::Screen(LocalFrame* frame) : DOMWindowClient(frame) {}
 
 int Screen::height() const {
   if (!frame())
@@ -135,7 +135,7 @@
 }
 
 DEFINE_TRACE(Screen) {
-  ContextClient::trace(visitor);
+  DOMWindowClient::trace(visitor);
   Supplementable<Screen>::trace(visitor);
 }
 
diff --git a/third_party/WebKit/Source/core/frame/Screen.h b/third_party/WebKit/Source/core/frame/Screen.h
index cfc9b8de..52ea557 100644
--- a/third_party/WebKit/Source/core/frame/Screen.h
+++ b/third_party/WebKit/Source/core/frame/Screen.h
@@ -41,7 +41,7 @@
 
 class CORE_EXPORT Screen final : public GarbageCollected<Screen>,
                                  public ScriptWrappable,
-                                 public ContextClient,
+                                 public DOMWindowClient,
                                  public Supplementable<Screen> {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(Screen);
diff --git a/third_party/WebKit/Source/core/inspector/ConsoleTypes.h b/third_party/WebKit/Source/core/inspector/ConsoleTypes.h
index d919b3a..9485f5c 100644
--- a/third_party/WebKit/Source/core/inspector/ConsoleTypes.h
+++ b/third_party/WebKit/Source/core/inspector/ConsoleTypes.h
@@ -19,7 +19,8 @@
   OtherMessageSource,
   DeprecationMessageSource,
   WorkerMessageSource,
-  ViolationMessageSource
+  ViolationMessageSource,
+  InterventionMessageSource
 };
 
 enum MessageLevel {
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
index 7d71f1b..a9cece0 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
@@ -2369,10 +2369,12 @@
     if (node->isFrameOwnerElement()) {
       Document* contentDocument =
           toHTMLFrameOwnerElement(node)->contentDocument();
-      contentDocument->updateStyleAndLayoutTree();
-      visitLayoutTreeNodes(contentDocument->documentElement(), layoutTreeNodes,
-                           cssPropertyWhitelist, styleToIndexMap,
-                           computedStyles);
+      if (contentDocument) {
+        contentDocument->updateStyleAndLayoutTree();
+        visitLayoutTreeNodes(contentDocument->documentElement(),
+                             layoutTreeNodes, cssPropertyWhitelist,
+                             styleToIndexMap, computedStyles);
+      }
     }
 
     LayoutObject* layoutObject = node->layoutObject();
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLogAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorLogAgent.cpp
index c7f51d70..f98fb16 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorLogAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorLogAgent.cpp
@@ -44,6 +44,8 @@
       return protocol::Log::LogEntry::SourceEnum::Worker;
     case ViolationMessageSource:
       return protocol::Log::LogEntry::SourceEnum::Violation;
+    case InterventionMessageSource:
+      return protocol::Log::LogEntry::SourceEnum::Intervention;
     default:
       return protocol::Log::LogEntry::SourceEnum::Other;
   }
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json
index 662d9e183..ee61904 100644
--- a/third_party/WebKit/Source/core/inspector/browser_protocol.json
+++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -4374,7 +4374,7 @@
                 "type": "object",
                 "description": "Log entry.",
                 "properties": [
-                    { "name": "source", "type": "string", "enum": ["xml", "javascript", "network", "storage", "appcache", "rendering", "security", "deprecation", "worker", "violation", "other"], "description": "Log entry source." },
+                    { "name": "source", "type": "string", "enum": ["xml", "javascript", "network", "storage", "appcache", "rendering", "security", "deprecation", "worker", "violation", "intervention", "other"], "description": "Log entry source." },
                     { "name": "level", "type": "string", "enum": ["log", "warning", "error", "debug", "info"], "description": "Log entry severity." },
                     { "name": "text", "type": "string", "description": "Logged text." },
                     { "name": "timestamp", "$ref": "Runtime.Timestamp", "description": "Timestamp when this entry was added." },
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index 1f83e595..ed47b75 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -57,7 +57,6 @@
 #include "core/paint/PaintInfo.h"
 #include "core/paint/PaintLayerPainter.h"
 #include "core/paint/PaintLayerStackingNodeIterator.h"
-#include "core/paint/PaintTiming.h"
 #include "core/paint/ScrollableAreaPainter.h"
 #include "core/paint/TransformRecorder.h"
 #include "core/plugins/PluginView.h"
@@ -3284,13 +3283,6 @@
   targetObject->invalidateDisplayItemClients(PaintInvalidationForTesting);
 }
 
-void CompositedLayerMapping::notifyPaint(bool isFirstPaint,
-                                         bool textPainted,
-                                         bool imagePainted) {
-  if (PaintTiming* timing = m_owningLayer.paintTiming())
-    timing->notifyPaint(isFirstPaint, textPainted, imagePainted);
-}
-
 IntRect CompositedLayerMapping::pixelSnappedCompositedBounds() const {
   LayoutRect bounds = m_compositedBounds;
   bounds.move(m_owningLayer.subpixelAccumulation());
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
index 3e98bde..1431b5d 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -204,10 +204,6 @@
 
   // GraphicsLayerClient interface
   void invalidateTargetElementForTesting() override;
-  void notifyPaint(bool isFirstPaint,
-                   bool textPainted,
-                   bool imagePainted) override;
-
   IntRect computeInterestRect(
       const GraphicsLayer*,
       const IntRect& previousInterestRect) const override;
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h
index 069cf91..416e2c1 100644
--- a/third_party/WebKit/Source/core/loader/EmptyClients.h
+++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -342,14 +342,9 @@
   void runScriptsAtDocumentReady(bool) override {}
 
   void didCreateScriptContext(v8::Local<v8::Context>,
-                              int extensionGroup,
                               int worldId) override {}
   void willReleaseScriptContext(v8::Local<v8::Context>, int worldId) override {}
-  bool allowScriptExtension(const String& extensionName,
-                            int extensionGroup,
-                            int worldId) override {
-    return false;
-  }
+  bool allowScriptExtensions() override { return false; }
 
   WebCookieJar* cookieJar() const override { return 0; }
 
diff --git a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
index 5332b9d3..3040bbe 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
+++ b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
@@ -218,13 +218,10 @@
   virtual void runScriptsAtDocumentReady(bool documentIsEmpty) = 0;
 
   virtual void didCreateScriptContext(v8::Local<v8::Context>,
-                                      int extensionGroup,
                                       int worldId) = 0;
   virtual void willReleaseScriptContext(v8::Local<v8::Context>,
                                         int worldId) = 0;
-  virtual bool allowScriptExtension(const String& extensionName,
-                                    int extensionGroup,
-                                    int worldId) = 0;
+  virtual bool allowScriptExtensions() = 0;
 
   virtual void didChangeScrollOffset() {}
   virtual void didUpdateCurrentHistoryItem() {}
diff --git a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
index a72902b..73f36287 100644
--- a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
@@ -668,6 +668,8 @@
   DCHECK(isMainThread());
   ResourceLoaderOptions resourceLoaderOptions = originalResourceLoaderOptions;
   resourceLoaderOptions.requestInitiatorContext = WorkerContext;
+  // TODO(yhirano): Remove this CHECK once https://crbug.com/667254 is fixed.
+  CHECK(!m_mainThreadLoader);
   m_mainThreadLoader = DocumentThreadableLoader::create(document, this, options,
                                                         resourceLoaderOptions);
   m_mainThreadLoader->start(ResourceRequest(request.get()));
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index d2992e3..f2e9e46 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -73,7 +73,6 @@
 #include "core/paint/BoxReflectionUtils.h"
 #include "core/paint/FilterEffectBuilder.h"
 #include "core/paint/ObjectPaintInvalidator.h"
-#include "core/paint/PaintTiming.h"
 #include "platform/LengthFunctions.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/geometry/FloatPoint3D.h"
@@ -3185,12 +3184,6 @@
   m_needsRepaint = false;
 }
 
-PaintTiming* PaintLayer::paintTiming() {
-  if (Node* node = layoutObject()->node())
-    return &PaintTiming::from(node->document());
-  return nullptr;
-}
-
 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
 void PaintLayer::endShouldKeepAliveAllClientsRecursive() {
   for (PaintLayer* child = firstChild(); child; child = child->nextSibling())
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h
index 3c9cec0..d0605ac 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.h
@@ -72,7 +72,6 @@
 class HitTestResult;
 class HitTestingTransformState;
 class PaintLayerCompositor;
-class PaintTiming;
 class TransformationMatrix;
 
 enum IncludeSelfOrNot { IncludeSelf, ExcludeSelf };
@@ -971,8 +970,6 @@
     m_previousPaintPhaseDescendantBlockBackgroundsWasEmpty = isEmpty;
   }
 
-  PaintTiming* paintTiming();
-
   ClipRectsCache* clipRectsCache() const { return m_clipRectsCache.get(); }
   ClipRectsCache& ensureClipRectsCache() const {
     if (!m_clipRectsCache)
diff --git a/third_party/WebKit/Source/core/paint/ViewPainter.cpp b/third_party/WebKit/Source/core/paint/ViewPainter.cpp
index ac91a1e..2d3ac26 100644
--- a/third_party/WebKit/Source/core/paint/ViewPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ViewPainter.cpp
@@ -167,12 +167,10 @@
       shouldDrawBackgroundInSeparateBuffer
           ? rootBackgroundColor
           : baseBackgroundColor.blend(rootBackgroundColor);
-  if (combinedBackgroundColor != frameView.baseBackgroundColor() &&
-      !context.getPaintController().nonDefaultBackgroundColorPainted()) {
-    TRACE_EVENT_INSTANT0("blink.user_timing", "paintNonDefaultBackgroundColor",
-                         TRACE_EVENT_SCOPE_GLOBAL);
-    context.getPaintController().setNonDefaultBackgroundColorPainted();
-  }
+
+  if (combinedBackgroundColor != frameView.baseBackgroundColor())
+    context.getPaintController().setFirstPainted();
+
   if (combinedBackgroundColor.alpha()) {
     if (!combinedBackgroundColor.hasAlpha() &&
         RuntimeEnabledFeatures::slimmingPaintV2Enabled())
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
index 148d751..e4402ca 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -1826,24 +1826,43 @@
   variables.setRegisteredVariable(name, parsedValue);
 }
 
-void ComputedStyle::removeInheritedVariable(const AtomicString& name) {
-  mutableInheritedVariables().removeVariable(name);
-}
-
-void ComputedStyle::removeNonInheritedVariable(const AtomicString& name) {
-  mutableNonInheritedVariables().removeVariable(name);
+void ComputedStyle::removeVariable(const AtomicString& name,
+                                   bool isInheritedProperty) {
+  if (isInheritedProperty) {
+    mutableInheritedVariables().removeVariable(name);
+  } else {
+    mutableNonInheritedVariables().removeVariable(name);
+  }
 }
 
 CSSVariableData* ComputedStyle::getVariable(const AtomicString& name) const {
-  if (inheritedVariables()) {
-    if (CSSVariableData* variable = inheritedVariables()->getVariable(name))
-      return variable;
+  CSSVariableData* variable = getVariable(name, true);
+  if (variable) {
+    return variable;
   }
-  if (nonInheritedVariables()) {
-    if (CSSVariableData* variable = nonInheritedVariables()->getVariable(name))
-      return variable;
+  return getVariable(name, false);
+}
+
+CSSVariableData* ComputedStyle::getVariable(const AtomicString& name,
+                                            bool isInheritedProperty) const {
+  if (isInheritedProperty) {
+    return inheritedVariables() ? inheritedVariables()->getVariable(name)
+                                : nullptr;
   }
-  return nullptr;
+  return nonInheritedVariables() ? nonInheritedVariables()->getVariable(name)
+                                 : nullptr;
+}
+
+const CSSValue* ComputedStyle::getRegisteredVariable(
+    const AtomicString& name,
+    bool isInheritedProperty) const {
+  if (isInheritedProperty) {
+    return inheritedVariables() ? inheritedVariables()->registeredVariable(name)
+                                : nullptr;
+  }
+  return nonInheritedVariables()
+             ? nonInheritedVariables()->registeredVariable(name)
+             : nullptr;
 }
 
 float ComputedStyle::wordSpacing() const {
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index 441d58b..825e0e5 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -2504,12 +2504,17 @@
                                        PassRefPtr<CSSVariableData>,
                                        const CSSValue*);
 
-  void removeInheritedVariable(const AtomicString&);
-  void removeNonInheritedVariable(const AtomicString&);
+  void removeVariable(const AtomicString&, bool isInheritedProperty);
 
   // Handles both inherited and non-inherited variables
   CSSVariableData* getVariable(const AtomicString&) const;
 
+  CSSVariableData* getVariable(const AtomicString&,
+                               bool isInheritedProperty) const;
+
+  const CSSValue* getRegisteredVariable(const AtomicString&,
+                                        bool isInheritedProperty) const;
+
   void setHasVariableReferenceFromNonInheritedProperty() {
     m_nonInheritedData.m_variableReference = true;
   }
diff --git a/third_party/WebKit/Source/core/style/StyleInheritedVariables.cpp b/third_party/WebKit/Source/core/style/StyleInheritedVariables.cpp
index 46a52ba..fc5e403 100644
--- a/third_party/WebKit/Source/core/style/StyleInheritedVariables.cpp
+++ b/third_party/WebKit/Source/core/style/StyleInheritedVariables.cpp
@@ -57,7 +57,7 @@
   m_registeredData.set(name, const_cast<CSSValue*>(parsedValue));
 }
 
-CSSValue* StyleInheritedVariables::registeredVariable(
+const CSSValue* StyleInheritedVariables::registeredVariable(
     const AtomicString& name) const {
   auto result = m_registeredData.find(name);
   if (result != m_registeredData.end())
diff --git a/third_party/WebKit/Source/core/style/StyleInheritedVariables.h b/third_party/WebKit/Source/core/style/StyleInheritedVariables.h
index 1668f321..bdd8c72 100644
--- a/third_party/WebKit/Source/core/style/StyleInheritedVariables.h
+++ b/third_party/WebKit/Source/core/style/StyleInheritedVariables.h
@@ -37,7 +37,7 @@
   void removeVariable(const AtomicString&);
 
   void setRegisteredVariable(const AtomicString&, const CSSValue*);
-  CSSValue* registeredVariable(const AtomicString&) const;
+  const CSSValue* registeredVariable(const AtomicString&) const;
 
   // This map will contain null pointers if variables are invalid due to
   // cycles or referencing invalid variables without using a fallback.
diff --git a/third_party/WebKit/Source/core/style/StyleNonInheritedVariables.h b/third_party/WebKit/Source/core/style/StyleNonInheritedVariables.h
index c7cec75a..ac7fa7b 100644
--- a/third_party/WebKit/Source/core/style/StyleNonInheritedVariables.h
+++ b/third_party/WebKit/Source/core/style/StyleNonInheritedVariables.h
@@ -36,7 +36,7 @@
   void removeVariable(const AtomicString&);
 
   void setRegisteredVariable(const AtomicString&, const CSSValue*);
-  CSSValue* registeredVariable(const AtomicString& name) const {
+  const CSSValue* registeredVariable(const AtomicString& name) const {
     return m_registeredData.get(name);
   }
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
index c0d1b07..64d6f9b 100644
--- a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
@@ -78,6 +78,8 @@
   ResourceLoaderOptions resourceLoaderOptions;
   resourceLoaderOptions.allowCredentials = AllowStoredCredentials;
 
+  // TODO(yhirano): Remove this CHECK once https://crbug.com/667254 is fixed.
+  CHECK(!m_threadableLoader);
   WorkerThreadableLoader::loadResourceSynchronously(
       toWorkerGlobalScope(executionContext), request, *this, options,
       resourceLoaderOptions);
@@ -108,6 +110,8 @@
   // (E.g. see crbug.com/524694 for why we can't easily remove this protect)
   RefPtr<WorkerScriptLoader> protect(this);
   m_needToCancel = true;
+  // TODO(yhirano): Remove this CHECK once https://crbug.com/667254 is fixed.
+  CHECK(!m_threadableLoader);
   m_threadableLoader = ThreadableLoader::create(executionContext, this, options,
                                                 resourceLoaderOptions);
   m_threadableLoader->start(request);
diff --git a/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp b/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp
index 65d73f6..c8394ee 100644
--- a/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp
+++ b/third_party/WebKit/Source/core/xml/DocumentXMLTreeViewer.cpp
@@ -24,7 +24,7 @@
   v8::HandleScope handleScope(V8PerIsolateData::mainThreadIsolate());
 
   document.frame()->script().executeScriptInIsolatedWorld(
-      WorldIdConstants::DocumentXMLTreeViewerWorldId, sources, 0, nullptr);
+      WorldIdConstants::DocumentXMLTreeViewerWorldId, sources, nullptr);
 
   Element* element = document.getElementById("xml-viewer-style");
   if (element) {
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index f987c2c076..eb210a4 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -95,9 +95,7 @@
   "front_end/common/Color.js",
   "front_end/common/Console.js",
   "front_end/common/ContentProvider.js",
-  "front_end/common/CSSShadowModel.js",
   "front_end/common/FormatterWorkerPool.js",
-  "front_end/common/Geometry.js",
   "front_end/common/module.json",
   "front_end/common/ModuleExtensionInterfaces.js",
   "front_end/common/Object.js",
@@ -263,6 +261,7 @@
   "front_end/inline_editor/ColorSwatch.js",
   "front_end/inline_editor/cssShadowEditor.css",
   "front_end/inline_editor/CSSShadowEditor.js",
+  "front_end/inline_editor/CSSShadowModel.js",
   "front_end/inline_editor/cssShadowSwatch.css",
   "front_end/inline_editor/module.json",
   "front_end/inline_editor/SwatchPopoverHelper.js",
@@ -362,9 +361,12 @@
   "front_end/profiler/HeapSnapshotGridNodes.js",
   "front_end/profiler/HeapSnapshotProxy.js",
   "front_end/profiler/HeapSnapshotView.js",
+  "front_end/profiler/MemoryProfilerPanel.js",
   "front_end/profiler/module.json",
   "front_end/profiler/ProfileDataGrid.js",
+  "front_end/profiler/ProfileHeader.js",
   "front_end/profiler/ProfileLauncherView.js",
+  "front_end/profiler/ProfileType.js",
   "front_end/profiler/profilesPanel.css",
   "front_end/profiler/ProfilesPanel.js",
   "front_end/profiler/profilesSidebarTree.css",
@@ -588,6 +590,7 @@
   "front_end/ui/filter.css",
   "front_end/ui/FilterBar.js",
   "front_end/ui/ForwardedInputEventHandler.js",
+  "front_end/ui/Geometry.js",
   "front_end/ui/HistoryInput.js",
   "front_end/ui/Icon.js",
   "front_end/ui/infobar.css",
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js
index 90c6e3d..a8b8dc5 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js
+++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationUI.js
@@ -175,7 +175,7 @@
       line.style.stroke = strokeColor;
     }
 
-    var bezier = Common.Geometry.CubicBezier.parse(easing);
+    var bezier = UI.Geometry.CubicBezier.parse(easing);
     var cache = this._cachedElements[iteration].keyframeRender;
     if (!cache[keyframeIndex]) {
       cache[keyframeIndex] = bezier ? parentElement.createSVGChild('path', 'animation-keyframe') :
diff --git a/third_party/WebKit/Source/devtools/front_end/common/CSSShadowModel.js b/third_party/WebKit/Source/devtools/front_end/common/CSSShadowModel.js
deleted file mode 100644
index a34098e..0000000
--- a/third_party/WebKit/Source/devtools/front_end/common/CSSShadowModel.js
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/**
- * @unrestricted
- */
-Common.CSSShadowModel = class {
-  /**
-   * @param {boolean} isBoxShadow
-   */
-  constructor(isBoxShadow) {
-    this._isBoxShadow = isBoxShadow;
-    this._inset = false;
-    this._offsetX = Common.CSSLength.zero();
-    this._offsetY = Common.CSSLength.zero();
-    this._blurRadius = Common.CSSLength.zero();
-    this._spreadRadius = Common.CSSLength.zero();
-    this._color = /** @type {!Common.Color} */ (Common.Color.parse('black'));
-    this._format = [Common.CSSShadowModel._Part.OffsetX, Common.CSSShadowModel._Part.OffsetY];
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Array<!Common.CSSShadowModel>}
-   */
-  static parseTextShadow(text) {
-    return Common.CSSShadowModel._parseShadow(text, false);
-  }
-
-  /**
-   * @param {string} text
-   * @return {!Array<!Common.CSSShadowModel>}
-   */
-  static parseBoxShadow(text) {
-    return Common.CSSShadowModel._parseShadow(text, true);
-  }
-
-  /**
-   * @param {string} text
-   * @param {boolean} isBoxShadow
-   * @return {!Array<!Common.CSSShadowModel>}
-   */
-  static _parseShadow(text, isBoxShadow) {
-    var shadowTexts = [];
-    // Split by commas that aren't inside of color values to get the individual shadow values.
-    var splits = Common.TextUtils.splitStringByRegexes(text, [Common.Color.Regex, /,/g]);
-    var currentIndex = 0;
-    for (var i = 0; i < splits.length; i++) {
-      if (splits[i].regexIndex === 1) {
-        var comma = splits[i];
-        shadowTexts.push(text.substring(currentIndex, comma.position));
-        currentIndex = comma.position + 1;
-      }
-    }
-    shadowTexts.push(text.substring(currentIndex, text.length));
-
-    var shadows = [];
-    for (var i = 0; i < shadowTexts.length; i++) {
-      var shadow = new Common.CSSShadowModel(isBoxShadow);
-      shadow._format = [];
-      var nextPartAllowed = true;
-      var regexes = [/inset/gi, Common.Color.Regex, Common.CSSLength.Regex];
-      var results = Common.TextUtils.splitStringByRegexes(shadowTexts[i], regexes);
-      for (var j = 0; j < results.length; j++) {
-        var result = results[j];
-        if (result.regexIndex === -1) {
-          // Don't allow anything other than inset, color, length values, and whitespace.
-          if (/\S/.test(result.value))
-            return [];
-          // All parts must be separated by whitespace.
-          nextPartAllowed = true;
-        } else {
-          if (!nextPartAllowed)
-            return [];
-          nextPartAllowed = false;
-
-          if (result.regexIndex === 0) {
-            shadow._inset = true;
-            shadow._format.push(Common.CSSShadowModel._Part.Inset);
-          } else if (result.regexIndex === 1) {
-            var color = Common.Color.parse(result.value);
-            if (!color)
-              return [];
-            shadow._color = color;
-            shadow._format.push(Common.CSSShadowModel._Part.Color);
-          } else if (result.regexIndex === 2) {
-            var length = Common.CSSLength.parse(result.value);
-            if (!length)
-              return [];
-            var previousPart = shadow._format.length > 0 ? shadow._format[shadow._format.length - 1] : '';
-            if (previousPart === Common.CSSShadowModel._Part.OffsetX) {
-              shadow._offsetY = length;
-              shadow._format.push(Common.CSSShadowModel._Part.OffsetY);
-            } else if (previousPart === Common.CSSShadowModel._Part.OffsetY) {
-              shadow._blurRadius = length;
-              shadow._format.push(Common.CSSShadowModel._Part.BlurRadius);
-            } else if (previousPart === Common.CSSShadowModel._Part.BlurRadius) {
-              shadow._spreadRadius = length;
-              shadow._format.push(Common.CSSShadowModel._Part.SpreadRadius);
-            } else {
-              shadow._offsetX = length;
-              shadow._format.push(Common.CSSShadowModel._Part.OffsetX);
-            }
-          }
-        }
-      }
-      if (invalidCount(Common.CSSShadowModel._Part.OffsetX, 1, 1) ||
-          invalidCount(Common.CSSShadowModel._Part.OffsetY, 1, 1) ||
-          invalidCount(Common.CSSShadowModel._Part.Color, 0, 1) ||
-          invalidCount(Common.CSSShadowModel._Part.BlurRadius, 0, 1) ||
-          invalidCount(Common.CSSShadowModel._Part.Inset, 0, isBoxShadow ? 1 : 0) ||
-          invalidCount(Common.CSSShadowModel._Part.SpreadRadius, 0, isBoxShadow ? 1 : 0))
-        return [];
-      shadows.push(shadow);
-    }
-    return shadows;
-
-    /**
-     * @param {string} part
-     * @param {number} min
-     * @param {number} max
-     * @return {boolean}
-     */
-    function invalidCount(part, min, max) {
-      var count = 0;
-      for (var i = 0; i < shadow._format.length; i++) {
-        if (shadow._format[i] === part)
-          count++;
-      }
-      return count < min || count > max;
-    }
-  }
-
-  /**
-   * @param {boolean} inset
-   */
-  setInset(inset) {
-    this._inset = inset;
-    if (this._format.indexOf(Common.CSSShadowModel._Part.Inset) === -1)
-      this._format.unshift(Common.CSSShadowModel._Part.Inset);
-  }
-
-  /**
-   * @param {!Common.CSSLength} offsetX
-   */
-  setOffsetX(offsetX) {
-    this._offsetX = offsetX;
-  }
-
-  /**
-   * @param {!Common.CSSLength} offsetY
-   */
-  setOffsetY(offsetY) {
-    this._offsetY = offsetY;
-  }
-
-  /**
-   * @param {!Common.CSSLength} blurRadius
-   */
-  setBlurRadius(blurRadius) {
-    this._blurRadius = blurRadius;
-    if (this._format.indexOf(Common.CSSShadowModel._Part.BlurRadius) === -1) {
-      var yIndex = this._format.indexOf(Common.CSSShadowModel._Part.OffsetY);
-      this._format.splice(yIndex + 1, 0, Common.CSSShadowModel._Part.BlurRadius);
-    }
-  }
-
-  /**
-   * @param {!Common.CSSLength} spreadRadius
-   */
-  setSpreadRadius(spreadRadius) {
-    this._spreadRadius = spreadRadius;
-    if (this._format.indexOf(Common.CSSShadowModel._Part.SpreadRadius) === -1) {
-      this.setBlurRadius(this._blurRadius);
-      var blurIndex = this._format.indexOf(Common.CSSShadowModel._Part.BlurRadius);
-      this._format.splice(blurIndex + 1, 0, Common.CSSShadowModel._Part.SpreadRadius);
-    }
-  }
-
-  /**
-   * @param {!Common.Color} color
-   */
-  setColor(color) {
-    this._color = color;
-    if (this._format.indexOf(Common.CSSShadowModel._Part.Color) === -1)
-      this._format.push(Common.CSSShadowModel._Part.Color);
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isBoxShadow() {
-    return this._isBoxShadow;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  inset() {
-    return this._inset;
-  }
-
-  /**
-   * @return {!Common.CSSLength}
-   */
-  offsetX() {
-    return this._offsetX;
-  }
-
-  /**
-   * @return {!Common.CSSLength}
-   */
-  offsetY() {
-    return this._offsetY;
-  }
-
-  /**
-   * @return {!Common.CSSLength}
-   */
-  blurRadius() {
-    return this._blurRadius;
-  }
-
-  /**
-   * @return {!Common.CSSLength}
-   */
-  spreadRadius() {
-    return this._spreadRadius;
-  }
-
-  /**
-   * @return {!Common.Color}
-   */
-  color() {
-    return this._color;
-  }
-
-  /**
-   * @return {string}
-   */
-  asCSSText() {
-    var parts = [];
-    for (var i = 0; i < this._format.length; i++) {
-      var part = this._format[i];
-      if (part === Common.CSSShadowModel._Part.Inset && this._inset)
-        parts.push('inset');
-      else if (part === Common.CSSShadowModel._Part.OffsetX)
-        parts.push(this._offsetX.asCSSText());
-      else if (part === Common.CSSShadowModel._Part.OffsetY)
-        parts.push(this._offsetY.asCSSText());
-      else if (part === Common.CSSShadowModel._Part.BlurRadius)
-        parts.push(this._blurRadius.asCSSText());
-      else if (part === Common.CSSShadowModel._Part.SpreadRadius)
-        parts.push(this._spreadRadius.asCSSText());
-      else if (part === Common.CSSShadowModel._Part.Color)
-        parts.push(this._color.asString(this._color.format()));
-    }
-    return parts.join(' ');
-  }
-};
-
-/**
- * @enum {string}
- */
-Common.CSSShadowModel._Part = {
-  Inset: 'I',
-  OffsetX: 'X',
-  OffsetY: 'Y',
-  BlurRadius: 'B',
-  SpreadRadius: 'S',
-  Color: 'C'
-};
-
-
-/**
- * @unrestricted
- */
-Common.CSSLength = class {
-  /**
-   * @param {number} amount
-   * @param {string} unit
-   */
-  constructor(amount, unit) {
-    this.amount = amount;
-    this.unit = unit;
-  }
-
-  /**
-   * @param {string} text
-   * @return {?Common.CSSLength}
-   */
-  static parse(text) {
-    var lengthRegex = new RegExp('^(?:' + Common.CSSLength.Regex.source + ')$', 'i');
-    var match = text.match(lengthRegex);
-    if (!match)
-      return null;
-    if (match.length > 2 && match[2])
-      return new Common.CSSLength(parseFloat(match[1]), match[2]);
-    return Common.CSSLength.zero();
-  }
-
-  /**
-   * @return {!Common.CSSLength}
-   */
-  static zero() {
-    return new Common.CSSLength(0, '');
-  }
-
-  /**
-   * @return {string}
-   */
-  asCSSText() {
-    return this.amount + this.unit;
-  }
-};
-
-/** @type {!RegExp} */
-Common.CSSLength.Regex = (function() {
-  var number = '([+-]?(?:[0-9]*[.])?[0-9]+(?:[eE][+-]?[0-9]+)?)';
-  var unit = '(ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmax|vmin|vw)';
-  var zero = '[+-]?(?:0*[.])?0+(?:[eE][+-]?[0-9]+)?';
-  return new RegExp(number + unit + '|' + zero, 'gi');
-})();
diff --git a/third_party/WebKit/Source/devtools/front_end/common/module.json b/third_party/WebKit/Source/devtools/front_end/common/module.json
index 5bed854..1072c6a4 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/common/module.json
@@ -7,10 +7,8 @@
         "TextDictionary.js",
         "Object.js",
         "Color.js",
-        "Geometry.js",
         "Console.js",
         "ContentProvider.js",
-        "CSSShadowModel.js",
         "ParsedURL.js",
         "Progress.js",
         "ResourceType.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ColorSwatchPopoverIcon.js b/third_party/WebKit/Source/devtools/front_end/elements/ColorSwatchPopoverIcon.js
index 4c9379a..3f8336c 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ColorSwatchPopoverIcon.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ColorSwatchPopoverIcon.js
@@ -33,10 +33,10 @@
     }
 
     this._bezierEditor = new InlineEditor.BezierEditor();
-    var cubicBezier = Common.Geometry.CubicBezier.parse(this._swatch.bezierText());
+    var cubicBezier = UI.Geometry.CubicBezier.parse(this._swatch.bezierText());
     if (!cubicBezier) {
       cubicBezier =
-          /** @type {!Common.Geometry.CubicBezier} */ (Common.Geometry.CubicBezier.parse('linear'));
+          /** @type {!UI.Geometry.CubicBezier} */ (UI.Geometry.CubicBezier.parse('linear'));
     }
     this._bezierEditor.setBezier(cubicBezier);
     this._bezierEditor.addEventListener(InlineEditor.BezierEditor.Events.BezierChanged, this._boundBezierChanged);
@@ -271,7 +271,7 @@
    * @param {!Common.Event} event
    */
   _shadowChanged(event) {
-    this._shadowSwatch.setCSSShadow(/** @type {!Common.CSSShadowModel} */ (event.data));
+    this._shadowSwatch.setCSSShadow(/** @type {!InlineEditor.CSSShadowModel} */ (event.data));
     this._treeElement.applyStyleText(this._treeElement.renderedPropertyText(), false);
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
index 4b004f4c..9cb007d 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
@@ -1924,7 +1924,7 @@
    * @return {!Node}
    */
   _processBezier(text) {
-    if (!this._editable() || !Common.Geometry.CubicBezier.parse(text))
+    if (!this._editable() || !UI.Geometry.CubicBezier.parse(text))
       return createTextNode(text);
     var swatchPopoverHelper = this._parentPane._swatchPopoverHelper;
     var swatch = InlineEditor.BezierSwatch.create();
@@ -1943,9 +1943,9 @@
       return createTextNode(propertyValue);
     var shadows;
     if (propertyName === 'text-shadow')
-      shadows = Common.CSSShadowModel.parseTextShadow(propertyValue);
+      shadows = InlineEditor.CSSShadowModel.parseTextShadow(propertyValue);
     else
-      shadows = Common.CSSShadowModel.parseBoxShadow(propertyValue);
+      shadows = InlineEditor.CSSShadowModel.parseBoxShadow(propertyValue);
     if (!shadows.length)
       return createTextNode(propertyValue);
     var container = createDocumentFragment();
@@ -3000,7 +3000,7 @@
     var regexes = [SDK.CSSMetadata.VariableRegex, SDK.CSSMetadata.URLRegex];
     var processors = [createTextNode, this._processURL.bind(this)];
     if (this._bezierHandler && SDK.cssMetadata().isBezierAwareProperty(this._propertyName)) {
-      regexes.push(Common.Geometry.CubicBezier.Regex);
+      regexes.push(UI.Geometry.CubicBezier.Regex);
       processors.push(this._bezierHandler);
     }
     if (this._colorHandler && SDK.cssMetadata().isColorAwareProperty(this._propertyName)) {
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js
index acea052b..bd206f7f 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeModel.js
@@ -11,13 +11,13 @@
    */
   constructor(updateCallback) {
     this._updateCallback = updateCallback;
-    this._screenRect = new Common.Rect(0, 0, 1, 1);
-    this._visiblePageRect = new Common.Rect(0, 0, 1, 1);
-    this._availableSize = new Size(1, 1);
-    this._preferredSize = new Size(1, 1);
+    this._screenRect = new UI.Rect(0, 0, 1, 1);
+    this._visiblePageRect = new UI.Rect(0, 0, 1, 1);
+    this._availableSize = new UI.Size(1, 1);
+    this._preferredSize = new UI.Size(1, 1);
     this._initialized = false;
     this._deviceMetricsThrottler = new Common.Throttler(0);
-    this._appliedDeviceSize = new Size(1, 1);
+    this._appliedDeviceSize = new UI.Size(1, 1);
     this._appliedDeviceScaleFactor = window.devicePixelRatio;
     this._appliedUserAgentType = Emulation.DeviceModeModel.UA.Desktop;
 
@@ -87,8 +87,8 @@
   }
 
   /**
-   * @param {!Size} availableSize
-   * @param {!Size} preferredSize
+   * @param {!UI.Size} availableSize
+   * @param {!UI.Size} preferredSize
    */
   setAvailableSize(availableSize, preferredSize) {
     this._availableSize = availableSize;
@@ -210,21 +210,21 @@
   }
 
   /**
-   * @return {!Common.Rect}
+   * @return {!UI.Rect}
    */
   outlineRect() {
     return this._outlineRect;
   }
 
   /**
-   * @return {!Common.Rect}
+   * @return {!UI.Rect}
    */
   screenRect() {
     return this._screenRect;
   }
 
   /**
-   * @return {!Common.Rect}
+   * @return {!UI.Rect}
    */
   visiblePageRect() {
     return this._visiblePageRect;
@@ -245,7 +245,7 @@
   }
 
   /**
-   * @return {!Size}
+   * @return {!UI.Size}
    */
   appliedDeviceSize() {
     return this._appliedDeviceSize;
@@ -371,10 +371,10 @@
   }
 
   /**
-   * @return {!Insets}
+   * @return {!UI.Insets}
    */
   _currentOutline() {
-    var outline = new Insets(0, 0, 0, 0);
+    var outline = new UI.Insets(0, 0, 0, 0);
     if (this._type !== Emulation.DeviceModeModel.Type.Device)
       return outline;
     var orientation = this._device.orientationByName(this._mode.orientation);
@@ -384,11 +384,11 @@
   }
 
   /**
-   * @return {!Insets}
+   * @return {!UI.Insets}
    */
   _currentInsets() {
     if (this._type !== Emulation.DeviceModeModel.Type.Device)
-      return new Insets(0, 0, 0, 0);
+      return new UI.Insets(0, 0, 0, 0);
     return this._mode.insets;
   }
 
@@ -412,7 +412,7 @@
             this._device.touch() ? Emulation.DeviceModeModel.UA.DesktopTouch : Emulation.DeviceModeModel.UA.Desktop;
       }
       this._applyDeviceMetrics(
-          new Size(orientation.width, orientation.height), insets, outline, this._scaleSetting.get(),
+          new UI.Size(orientation.width, orientation.height), insets, outline, this._scaleSetting.get(),
           this._device.deviceScaleFactor, this._device.mobile(),
           this._mode.orientation === Emulation.EmulatedDevice.Horizontal ? 'landscapePrimary' : 'portraitPrimary',
           resetPageScaleFactor);
@@ -422,7 +422,8 @@
       this._fitScale = this._calculateFitScale(this._availableSize.width, this._availableSize.height);
       this._appliedUserAgentType = Emulation.DeviceModeModel.UA.Desktop;
       this._applyDeviceMetrics(
-          this._availableSize, new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), 1, 0, false, '', resetPageScaleFactor);
+          this._availableSize, new UI.Insets(0, 0, 0, 0), new UI.Insets(0, 0, 0, 0), 1, 0, false, '',
+          resetPageScaleFactor);
       this._applyUserAgent('');
       this._applyTouch(false, false);
     } else if (this._type === Emulation.DeviceModeModel.Type.Responsive) {
@@ -438,8 +439,8 @@
       this._fitScale = this._calculateFitScale(this._widthSetting.get(), this._heightSetting.get());
       this._appliedUserAgentType = this._uaSetting.get();
       this._applyDeviceMetrics(
-          new Size(screenWidth, screenHeight), new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), this._scaleSetting.get(),
-          this._deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile,
+          new UI.Size(screenWidth, screenHeight), new UI.Insets(0, 0, 0, 0), new UI.Insets(0, 0, 0, 0),
+          this._scaleSetting.get(), this._deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile,
           screenHeight >= screenWidth ? 'portraitPrimary' : 'landscapePrimary', resetPageScaleFactor);
       this._applyUserAgent(mobile ? Emulation.DeviceModeModel._defaultMobileUserAgent : '');
       this._applyTouch(
@@ -455,8 +456,8 @@
   /**
    * @param {number} screenWidth
    * @param {number} screenHeight
-   * @param {!Insets=} outline
-   * @param {!Insets=} insets
+   * @param {!UI.Insets=} outline
+   * @param {!UI.Insets=} insets
    * @return {number}
    */
   _calculateFitScale(screenWidth, screenHeight, outline, insets) {
@@ -500,9 +501,9 @@
   }
 
   /**
-   * @param {!Size} screenSize
-   * @param {!Insets} insets
-   * @param {!Insets} outline
+   * @param {!UI.Size} screenSize
+   * @param {!UI.Insets} insets
+   * @param {!UI.Insets} outline
    * @param {number} scale
    * @param {number} deviceScaleFactor
    * @param {boolean} mobile
@@ -530,13 +531,13 @@
 
     this._appliedDeviceSize = screenSize;
     this._appliedDeviceScaleFactor = deviceScaleFactor || window.devicePixelRatio;
-    this._screenRect = new Common.Rect(
+    this._screenRect = new UI.Rect(
         Math.max(0, (this._availableSize.width - screenSize.width * scale) / 2), outline.top * scale,
         screenSize.width * scale, screenSize.height * scale);
-    this._outlineRect = new Common.Rect(
+    this._outlineRect = new UI.Rect(
         this._screenRect.left - outline.left * scale, 0, (outline.left + screenSize.width + outline.right) * scale,
         (outline.top + screenSize.height + outline.bottom) * scale);
-    this._visiblePageRect = new Common.Rect(
+    this._visiblePageRect = new UI.Rect(
         positionX * scale, positionY * scale,
         Math.min(pageWidth * scale, this._availableSize.width - this._screenRect.left - positionX * scale),
         Math.min(pageHeight * scale, this._availableSize.height - this._screenRect.top - positionY * scale));
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeView.js b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeView.js
index ce6aef2..e554590 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeView.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeView.js
@@ -132,7 +132,7 @@
    */
   _onResizeStart(event) {
     this._slowPositionStart = null;
-    /** @type {!Size} */
+    /** @type {!UI.Size} */
     this._resizeStart = this._model.screenRect().size();
   }
 
@@ -182,7 +182,7 @@
   _updateUI() {
     /**
      * @param {!Element} element
-     * @param {!Common.Rect} rect
+     * @param {!UI.Rect} rect
      */
     function applyRect(element, rect) {
       element.style.left = rect.left + 'px';
@@ -310,8 +310,8 @@
   _contentAreaResized() {
     var zoomFactor = UI.zoomManager.zoomFactor();
     var rect = this._contentArea.getBoundingClientRect();
-    var availableSize = new Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
-    var preferredSize = new Size(
+    var availableSize = new UI.Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
+    var preferredSize = new UI.Size(
         Math.max((rect.width - 2 * this._handleWidth) * zoomFactor, 1),
         Math.max((rect.height - this._handleHeight) * zoomFactor, 1));
     this._model.setAvailableSize(availableSize, preferredSize);
@@ -367,7 +367,7 @@
 
     var zoomFactor = UI.zoomManager.zoomFactor();
     var rect = this._contentArea.getBoundingClientRect();
-    var availableSize = new Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
+    var availableSize = new UI.Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
     var outlineVisible = this._model.deviceOutlineSetting().get();
 
     if (availableSize.width < this._model.screenRect().width ||
@@ -421,7 +421,7 @@
 
       /**
        * @param {string} src
-       * @param {!Common.Rect} rect
+       * @param {!UI.Rect} rect
        * @return {!Promise<undefined>}
        */
       function paintImage(src, rect) {
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/DevicesSettingsTab.js b/third_party/WebKit/Source/devtools/front_end/emulation/DevicesSettingsTab.js
index 2312000..2c0a283b 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/DevicesSettingsTab.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/DevicesSettingsTab.js
@@ -148,9 +148,9 @@
     device.userAgent = editor.control('user-agent').value;
     device.modes = [];
     device.modes.push(
-        {title: '', orientation: Emulation.EmulatedDevice.Vertical, insets: new Insets(0, 0, 0, 0), image: null});
+        {title: '', orientation: Emulation.EmulatedDevice.Vertical, insets: new UI.Insets(0, 0, 0, 0), image: null});
     device.modes.push(
-        {title: '', orientation: Emulation.EmulatedDevice.Horizontal, insets: new Insets(0, 0, 0, 0), image: null});
+        {title: '', orientation: Emulation.EmulatedDevice.Horizontal, insets: new UI.Insets(0, 0, 0, 0), image: null});
     device.capabilities = [];
     var uaType = editor.control('ua-type').value;
     if (uaType === Emulation.DeviceModeModel.UA.Mobile || uaType === Emulation.DeviceModeModel.UA.MobileNoTouch)
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/EmulatedDevices.js b/third_party/WebKit/Source/devtools/front_end/emulation/EmulatedDevices.js
index 9178966..caf8827 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/EmulatedDevices.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/EmulatedDevices.js
@@ -71,10 +71,10 @@
 
       /**
        * @param {*} json
-       * @return {!Insets}
+       * @return {!UI.Insets}
        */
       function parseInsets(json) {
-        return new Insets(
+        return new UI.Insets(
             parseIntValue(json, 'left'), parseIntValue(json, 'top'), parseIntValue(json, 'right'),
             parseIntValue(json, 'bottom'));
       }
@@ -330,10 +330,10 @@
   }
 };
 
-/** @typedef {!{title: string, orientation: string, insets: !Insets, image: ?string}} */
+/** @typedef {!{title: string, orientation: string, insets: !UI.Insets, image: ?string}} */
 Emulation.EmulatedDevice.Mode;
 
-/** @typedef {!{width: number, height: number, outlineInsets: ?Insets, outlineImage: ?string}} */
+/** @typedef {!{width: number, height: number, outlineInsets: ?UI.Insets, outlineImage: ?string}} */
 Emulation.EmulatedDevice.Orientation;
 
 Emulation.EmulatedDevice.Horizontal = 'horizontal';
@@ -420,11 +420,15 @@
           device.modes.push({
             title: '',
             orientation: Emulation.EmulatedDevice.Horizontal,
-            insets: new Insets(0, 0, 0, 0),
+            insets: new UI.Insets(0, 0, 0, 0),
             image: null
           });
-          device.modes.push(
-              {title: '', orientation: Emulation.EmulatedDevice.Vertical, insets: new Insets(0, 0, 0, 0), image: null});
+          device.modes.push({
+            title: '',
+            orientation: Emulation.EmulatedDevice.Vertical,
+            insets: new UI.Insets(0, 0, 0, 0),
+            image: null
+          });
         }
       } else {
         success = false;
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/SensorsView.js b/third_party/WebKit/Source/devtools/front_end/emulation/SensorsView.js
index b3dc736..29b2eed 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/SensorsView.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/SensorsView.js
@@ -343,7 +343,7 @@
     var matrix = new WebKitCSSMatrix();
     this._boxMatrix = matrix.rotate(-deviceOrientation.beta, deviceOrientation.gamma, -deviceOrientation.alpha);
     var eulerAngles =
-        new Common.Geometry.EulerAngles(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
+        new UI.Geometry.EulerAngles(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
     this._orientationLayer.style.transform = eulerAngles.toRotate3DString();
   }
 
@@ -359,11 +359,11 @@
     event.consume(true);
     var axis, angle;
     if (event.shiftKey) {
-      axis = new Common.Geometry.Vector(0, 0, -1);
+      axis = new UI.Geometry.Vector(0, 0, -1);
       angle = (this._mouseDownVector.x - mouseMoveVector.x) * Emulation.SensorsView.ShiftDragOrientationSpeed;
     } else {
-      axis = Common.Geometry.crossProduct(this._mouseDownVector, mouseMoveVector);
-      angle = Common.Geometry.calculateAngle(this._mouseDownVector, mouseMoveVector);
+      axis = UI.Geometry.crossProduct(this._mouseDownVector, mouseMoveVector);
+      angle = UI.Geometry.calculateAngle(this._mouseDownVector, mouseMoveVector);
     }
 
     // The mouse movement vectors occur in the screen space, which is offset by 90 degrees from
@@ -374,7 +374,7 @@
                         .rotate(90, 0, 0)
                         .multiply(this._originalBoxMatrix);
 
-    var eulerAngles = Common.Geometry.EulerAngles.fromRotationMatrix(currentMatrix);
+    var eulerAngles = UI.Geometry.EulerAngles.fromRotationMatrix(currentMatrix);
     var newOrientation = new Emulation.DeviceOrientation(-eulerAngles.alpha, -eulerAngles.beta, eulerAngles.gamma);
     this._setDeviceOrientation(newOrientation, Emulation.SensorsView.DeviceOrientationModificationSource.UserDrag);
     this._setSelectElementLabel(this._orientationSelectElement, Emulation.SensorsView.NonPresetOptions.Custom);
@@ -402,7 +402,7 @@
   /**
    * @param {number} x
    * @param {number} y
-   * @return {?Common.Geometry.Vector}
+   * @return {?UI.Geometry.Vector}
    */
   _calculateRadiusVector(x, y) {
     var rect = this._stageElement.getBoundingClientRect();
@@ -411,9 +411,9 @@
     var sphereY = (y - rect.top - rect.height / 2) / radius;
     var sqrSum = sphereX * sphereX + sphereY * sphereY;
     if (sqrSum > 0.5)
-      return new Common.Geometry.Vector(sphereX, sphereY, 0.5 / Math.sqrt(sqrSum));
+      return new UI.Geometry.Vector(sphereX, sphereY, 0.5 / Math.sqrt(sqrSum));
 
-    return new Common.Geometry.Vector(sphereX, sphereY, Math.sqrt(1 - sqrSum));
+    return new UI.Geometry.Vector(sphereX, sphereY, Math.sqrt(1 - sqrSum));
   }
 
   _appendTouchControl() {
diff --git a/third_party/WebKit/Source/devtools/front_end/inline_editor/BezierEditor.js b/third_party/WebKit/Source/devtools/front_end/inline_editor/BezierEditor.js
index 397f8b3..ef6d1bd 100644
--- a/third_party/WebKit/Source/devtools/front_end/inline_editor/BezierEditor.js
+++ b/third_party/WebKit/Source/devtools/front_end/inline_editor/BezierEditor.js
@@ -44,7 +44,7 @@
   }
 
   /**
-   * @param {?Common.Geometry.CubicBezier} bezier
+   * @param {?UI.Geometry.CubicBezier} bezier
    */
   setBezier(bezier) {
     if (!bezier)
@@ -54,7 +54,7 @@
   }
 
   /**
-   * @return {!Common.Geometry.CubicBezier}
+   * @return {!UI.Geometry.CubicBezier}
    */
   bezier() {
     return this._bezier;
@@ -97,9 +97,9 @@
    * @return {boolean}
    */
   _dragStart(event) {
-    this._mouseDownPosition = new Common.Geometry.Point(event.x, event.y);
+    this._mouseDownPosition = new UI.Geometry.Point(event.x, event.y);
     var ui = this._curveUI;
-    this._controlPosition = new Common.Geometry.Point(
+    this._controlPosition = new UI.Geometry.Point(
         Number.constrain((event.offsetX - ui.radius) / ui.curveWidth(), 0, 1),
         (ui.curveHeight() + ui.marginTop + ui.radius - event.offsetY) / ui.curveHeight());
 
@@ -122,7 +122,7 @@
   _updateControlPosition(mouseX, mouseY) {
     var deltaX = (mouseX - this._mouseDownPosition.x) / this._curveUI.curveWidth();
     var deltaY = (mouseY - this._mouseDownPosition.y) / this._curveUI.curveHeight();
-    var newPosition = new Common.Geometry.Point(
+    var newPosition = new UI.Geometry.Point(
         Number.constrain(this._controlPosition.x + deltaX, 0, 1), this._controlPosition.y - deltaY);
     this._bezier.controlPoints[this._selectedPoint] = newPosition;
   }
@@ -152,7 +152,7 @@
     var presetElement = createElementWithClass('div', 'bezier-preset-category');
     var iconElement = presetElement.createSVGChild('svg', 'bezier-preset monospace');
     var category = {presets: presetGroup, presetIndex: 0, icon: presetElement};
-    this._presetUI.drawCurve(Common.Geometry.CubicBezier.parse(category.presets[0].value), iconElement);
+    this._presetUI.drawCurve(UI.Geometry.CubicBezier.parse(category.presets[0].value), iconElement);
     iconElement.addEventListener('click', this._presetCategorySelected.bind(this, category));
     return category;
   }
@@ -190,7 +190,7 @@
     this._header.classList.add('bezier-header-active');
     this._selectedCategory = category;
     this._selectedCategory.icon.classList.add('bezier-preset-selected');
-    this.setBezier(Common.Geometry.CubicBezier.parse(category.presets[category.presetIndex].value));
+    this.setBezier(UI.Geometry.CubicBezier.parse(category.presets[category.presetIndex].value));
     this._onchange();
     this._startPreviewAnimation();
     if (event)
@@ -208,7 +208,7 @@
     var length = this._selectedCategory.presets.length;
     this._selectedCategory.presetIndex = (this._selectedCategory.presetIndex + (intensify ? 1 : -1) + length) % length;
     this.setBezier(
-        Common.Geometry.CubicBezier.parse(this._selectedCategory.presets[this._selectedCategory.presetIndex].value));
+        UI.Geometry.CubicBezier.parse(this._selectedCategory.presets[this._selectedCategory.presetIndex].value));
     this._onchange();
     this._startPreviewAnimation();
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/inline_editor/BezierUI.js b/third_party/WebKit/Source/devtools/front_end/inline_editor/BezierUI.js
index 64873537..e03bdd7 100644
--- a/third_party/WebKit/Source/devtools/front_end/inline_editor/BezierUI.js
+++ b/third_party/WebKit/Source/devtools/front_end/inline_editor/BezierUI.js
@@ -21,7 +21,7 @@
   }
 
   /**
-   * @param {!Common.Geometry.CubicBezier} bezier
+   * @param {!UI.Geometry.CubicBezier} bezier
    * @param {!Element} path
    * @param {number} width
    */
@@ -89,7 +89,7 @@
   }
 
   /**
-   * @param {?Common.Geometry.CubicBezier} bezier
+   * @param {?UI.Geometry.CubicBezier} bezier
    * @param {!Element} svg
    */
   drawCurve(bezier, svg) {
@@ -107,13 +107,13 @@
 
     var curve = group.createSVGChild('path', 'bezier-path');
     var curvePoints = [
-      new Common.Geometry.Point(
+      new UI.Geometry.Point(
           bezier.controlPoints[0].x * width + this.radius,
           (1 - bezier.controlPoints[0].y) * height + this.radius + this.marginTop),
-      new Common.Geometry.Point(
+      new UI.Geometry.Point(
           bezier.controlPoints[1].x * width + this.radius,
           (1 - bezier.controlPoints[1].y) * height + this.radius + this.marginTop),
-      new Common.Geometry.Point(width + this.radius, this.marginTop + this.radius)
+      new UI.Geometry.Point(width + this.radius, this.marginTop + this.radius)
     ];
     curve.setAttribute(
         'd', 'M' + this.radius + ',' + (height + this.radius + this.marginTop) + ' C' + curvePoints.join(' '));
diff --git a/third_party/WebKit/Source/devtools/front_end/inline_editor/CSSShadowEditor.js b/third_party/WebKit/Source/devtools/front_end/inline_editor/CSSShadowEditor.js
index 58ec203..f8c0f18 100644
--- a/third_party/WebKit/Source/devtools/front_end/inline_editor/CSSShadowEditor.js
+++ b/third_party/WebKit/Source/devtools/front_end/inline_editor/CSSShadowEditor.js
@@ -81,7 +81,7 @@
   }
 
   /**
-   * @param {!Common.CSSShadowModel} model
+   * @param {!InlineEditor.CSSShadowModel} model
    */
   setModel(model) {
     this._model = model;
@@ -168,7 +168,7 @@
     var modifiedValue = UI.createReplacementString(event.currentTarget.value, event, customNumberHandler);
     if (!modifiedValue)
       return;
-    var length = Common.CSSLength.parse(modifiedValue);
+    var length = InlineEditor.CSSLength.parse(modifiedValue);
     if (!length)
       return;
     if (event.currentTarget === this._blurInput && length.amount < 0)
@@ -198,7 +198,7 @@
   _onTextInput(event) {
     this._changedElement = event.currentTarget;
     this._changedElement.classList.remove('invalid');
-    var length = Common.CSSLength.parse(event.currentTarget.value);
+    var length = InlineEditor.CSSLength.parse(event.currentTarget.value);
     if (!length || event.currentTarget === this._blurInput && length.amount < 0)
       return;
     if (event.currentTarget === this._xInput) {
@@ -220,10 +220,10 @@
   _onTextBlur() {
     if (!this._changedElement)
       return;
-    var length = !this._changedElement.value.trim() ? Common.CSSLength.zero() :
-                                                      Common.CSSLength.parse(this._changedElement.value);
+    var length = !this._changedElement.value.trim() ? InlineEditor.CSSLength.zero() :
+                                                      InlineEditor.CSSLength.parse(this._changedElement.value);
     if (!length)
-      length = Common.CSSLength.parse(this._changedElement.value + InlineEditor.CSSShadowEditor.defaultUnit);
+      length = InlineEditor.CSSLength.parse(this._changedElement.value + InlineEditor.CSSShadowEditor.defaultUnit);
     if (!length) {
       this._changedElement.classList.add('invalid');
       this._changedElement = null;
@@ -239,7 +239,7 @@
       this._updateCanvas(false);
     } else if (this._changedElement === this._blurInput) {
       if (length.amount < 0)
-        length = Common.CSSLength.zero();
+        length = InlineEditor.CSSLength.zero();
       this._model.setBlurRadius(length);
       this._blurInput.value = length.asCSSText();
       this._blurSlider.value = length.amount;
@@ -257,12 +257,12 @@
    */
   _onSliderInput(event) {
     if (event.currentTarget === this._blurSlider) {
-      this._model.setBlurRadius(new Common.CSSLength(
+      this._model.setBlurRadius(new InlineEditor.CSSLength(
           this._blurSlider.value, this._model.blurRadius().unit || InlineEditor.CSSShadowEditor.defaultUnit));
       this._blurInput.value = this._model.blurRadius().asCSSText();
       this._blurInput.classList.remove('invalid');
     } else if (event.currentTarget === this._spreadSlider) {
-      this._model.setSpreadRadius(new Common.CSSLength(
+      this._model.setSpreadRadius(new InlineEditor.CSSLength(
           this._spreadSlider.value, this._model.spreadRadius().unit || InlineEditor.CSSShadowEditor.defaultUnit));
       this._spreadInput.value = this._model.spreadRadius().asCSSText();
       this._spreadInput.classList.remove('invalid');
@@ -277,10 +277,10 @@
   _dragStart(event) {
     this._xySlider.focus();
     this._updateCanvas(true);
-    this._canvasOrigin = new Common.Geometry.Point(
+    this._canvasOrigin = new UI.Geometry.Point(
         this._xySlider.totalOffsetLeft() + this._halfCanvasSize,
         this._xySlider.totalOffsetTop() + this._halfCanvasSize);
-    var clickedPoint = new Common.Geometry.Point(event.x - this._canvasOrigin.x, event.y - this._canvasOrigin.y);
+    var clickedPoint = new UI.Geometry.Point(event.x - this._canvasOrigin.x, event.y - this._canvasOrigin.y);
     var thumbPoint = this._sliderThumbPosition();
     if (clickedPoint.distanceTo(thumbPoint) >= InlineEditor.CSSShadowEditor.sliderThumbRadius)
       this._dragMove(event);
@@ -291,7 +291,7 @@
    * @param {!MouseEvent} event
    */
   _dragMove(event) {
-    var point = new Common.Geometry.Point(event.x - this._canvasOrigin.x, event.y - this._canvasOrigin.y);
+    var point = new UI.Geometry.Point(event.x - this._canvasOrigin.x, event.y - this._canvasOrigin.y);
     if (event.shiftKey)
       point = this._snapToClosestDirection(point);
     var constrainedPoint = this._constrainPoint(point, this._innerCanvasSize);
@@ -300,17 +300,17 @@
 
     if (event.shiftKey) {
       this._model.setOffsetX(
-          new Common.CSSLength(newX, this._model.offsetX().unit || InlineEditor.CSSShadowEditor.defaultUnit));
+          new InlineEditor.CSSLength(newX, this._model.offsetX().unit || InlineEditor.CSSShadowEditor.defaultUnit));
       this._model.setOffsetY(
-          new Common.CSSLength(newY, this._model.offsetY().unit || InlineEditor.CSSShadowEditor.defaultUnit));
+          new InlineEditor.CSSLength(newY, this._model.offsetY().unit || InlineEditor.CSSShadowEditor.defaultUnit));
     } else {
       if (!event.altKey) {
         this._model.setOffsetX(
-            new Common.CSSLength(newX, this._model.offsetX().unit || InlineEditor.CSSShadowEditor.defaultUnit));
+            new InlineEditor.CSSLength(newX, this._model.offsetX().unit || InlineEditor.CSSShadowEditor.defaultUnit));
       }
       if (!UI.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
         this._model.setOffsetY(
-            new Common.CSSLength(newY, this._model.offsetY().unit || InlineEditor.CSSShadowEditor.defaultUnit));
+            new InlineEditor.CSSLength(newY, this._model.offsetY().unit || InlineEditor.CSSShadowEditor.defaultUnit));
       }
     }
     this._xInput.value = this._model.offsetX().asCSSText();
@@ -350,7 +350,8 @@
           offsetX.amount + shiftX, -InlineEditor.CSSShadowEditor.maxRange, InlineEditor.CSSShadowEditor.maxRange);
       if (newAmount === offsetX.amount)
         return;
-      this._model.setOffsetX(new Common.CSSLength(newAmount, offsetX.unit || InlineEditor.CSSShadowEditor.defaultUnit));
+      this._model.setOffsetX(
+          new InlineEditor.CSSLength(newAmount, offsetX.unit || InlineEditor.CSSShadowEditor.defaultUnit));
       this._xInput.value = this._model.offsetX().asCSSText();
       this._xInput.classList.remove('invalid');
     }
@@ -360,7 +361,8 @@
           offsetY.amount + shiftY, -InlineEditor.CSSShadowEditor.maxRange, InlineEditor.CSSShadowEditor.maxRange);
       if (newAmount === offsetY.amount)
         return;
-      this._model.setOffsetY(new Common.CSSLength(newAmount, offsetY.unit || InlineEditor.CSSShadowEditor.defaultUnit));
+      this._model.setOffsetY(
+          new InlineEditor.CSSLength(newAmount, offsetY.unit || InlineEditor.CSSShadowEditor.defaultUnit));
       this._yInput.value = this._model.offsetY().asCSSText();
       this._yInput.classList.remove('invalid');
     }
@@ -369,29 +371,29 @@
   }
 
   /**
-   * @param {!Common.Geometry.Point} point
+   * @param {!UI.Geometry.Point} point
    * @param {number} max
-   * @return {!Common.Geometry.Point}
+   * @return {!UI.Geometry.Point}
    */
   _constrainPoint(point, max) {
     if (Math.abs(point.x) <= max && Math.abs(point.y) <= max)
-      return new Common.Geometry.Point(point.x, point.y);
+      return new UI.Geometry.Point(point.x, point.y);
     return point.scale(max / Math.max(Math.abs(point.x), Math.abs(point.y)));
   }
 
   /**
-   * @param {!Common.Geometry.Point} point
-   * @return {!Common.Geometry.Point}
+   * @param {!UI.Geometry.Point} point
+   * @return {!UI.Geometry.Point}
    */
   _snapToClosestDirection(point) {
     var minDistance = Number.MAX_VALUE;
     var closestPoint = point;
 
     var directions = [
-      new Common.Geometry.Point(0, -1),  // North
-      new Common.Geometry.Point(1, -1),  // Northeast
-      new Common.Geometry.Point(1, 0),   // East
-      new Common.Geometry.Point(1, 1)    // Southeast
+      new UI.Geometry.Point(0, -1),  // North
+      new UI.Geometry.Point(1, -1),  // Northeast
+      new UI.Geometry.Point(1, 0),   // East
+      new UI.Geometry.Point(1, 1)    // Southeast
     ];
 
     for (var direction of directions) {
@@ -407,12 +409,12 @@
   }
 
   /**
-   * @return {!Common.Geometry.Point}
+   * @return {!UI.Geometry.Point}
    */
   _sliderThumbPosition() {
     var x = (this._model.offsetX().amount / InlineEditor.CSSShadowEditor.maxRange) * this._innerCanvasSize;
     var y = (this._model.offsetY().amount / InlineEditor.CSSShadowEditor.maxRange) * this._innerCanvasSize;
-    return this._constrainPoint(new Common.Geometry.Point(x, y), this._innerCanvasSize);
+    return this._constrainPoint(new UI.Geometry.Point(x, y), this._innerCanvasSize);
   }
 };
 
diff --git a/third_party/WebKit/Source/devtools/front_end/inline_editor/CSSShadowModel.js b/third_party/WebKit/Source/devtools/front_end/inline_editor/CSSShadowModel.js
new file mode 100644
index 0000000..66ef9e3b
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/inline_editor/CSSShadowModel.js
@@ -0,0 +1,323 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+/**
+ * @unrestricted
+ */
+InlineEditor.CSSShadowModel = class {
+  /**
+   * @param {boolean} isBoxShadow
+   */
+  constructor(isBoxShadow) {
+    this._isBoxShadow = isBoxShadow;
+    this._inset = false;
+    this._offsetX = InlineEditor.CSSLength.zero();
+    this._offsetY = InlineEditor.CSSLength.zero();
+    this._blurRadius = InlineEditor.CSSLength.zero();
+    this._spreadRadius = InlineEditor.CSSLength.zero();
+    this._color = /** @type {!Common.Color} */ (Common.Color.parse('black'));
+    this._format = [InlineEditor.CSSShadowModel._Part.OffsetX, InlineEditor.CSSShadowModel._Part.OffsetY];
+  }
+
+  /**
+   * @param {string} text
+   * @return {!Array<!InlineEditor.CSSShadowModel>}
+   */
+  static parseTextShadow(text) {
+    return InlineEditor.CSSShadowModel._parseShadow(text, false);
+  }
+
+  /**
+   * @param {string} text
+   * @return {!Array<!InlineEditor.CSSShadowModel>}
+   */
+  static parseBoxShadow(text) {
+    return InlineEditor.CSSShadowModel._parseShadow(text, true);
+  }
+
+  /**
+   * @param {string} text
+   * @param {boolean} isBoxShadow
+   * @return {!Array<!InlineEditor.CSSShadowModel>}
+   */
+  static _parseShadow(text, isBoxShadow) {
+    var shadowTexts = [];
+    // Split by commas that aren't inside of color values to get the individual shadow values.
+    var splits = Common.TextUtils.splitStringByRegexes(text, [Common.Color.Regex, /,/g]);
+    var currentIndex = 0;
+    for (var i = 0; i < splits.length; i++) {
+      if (splits[i].regexIndex === 1) {
+        var comma = splits[i];
+        shadowTexts.push(text.substring(currentIndex, comma.position));
+        currentIndex = comma.position + 1;
+      }
+    }
+    shadowTexts.push(text.substring(currentIndex, text.length));
+
+    var shadows = [];
+    for (var i = 0; i < shadowTexts.length; i++) {
+      var shadow = new InlineEditor.CSSShadowModel(isBoxShadow);
+      shadow._format = [];
+      var nextPartAllowed = true;
+      var regexes = [/inset/gi, Common.Color.Regex, InlineEditor.CSSLength.Regex];
+      var results = Common.TextUtils.splitStringByRegexes(shadowTexts[i], regexes);
+      for (var j = 0; j < results.length; j++) {
+        var result = results[j];
+        if (result.regexIndex === -1) {
+          // Don't allow anything other than inset, color, length values, and whitespace.
+          if (/\S/.test(result.value))
+            return [];
+          // All parts must be separated by whitespace.
+          nextPartAllowed = true;
+        } else {
+          if (!nextPartAllowed)
+            return [];
+          nextPartAllowed = false;
+
+          if (result.regexIndex === 0) {
+            shadow._inset = true;
+            shadow._format.push(InlineEditor.CSSShadowModel._Part.Inset);
+          } else if (result.regexIndex === 1) {
+            var color = Common.Color.parse(result.value);
+            if (!color)
+              return [];
+            shadow._color = color;
+            shadow._format.push(InlineEditor.CSSShadowModel._Part.Color);
+          } else if (result.regexIndex === 2) {
+            var length = InlineEditor.CSSLength.parse(result.value);
+            if (!length)
+              return [];
+            var previousPart = shadow._format.length > 0 ? shadow._format[shadow._format.length - 1] : '';
+            if (previousPart === InlineEditor.CSSShadowModel._Part.OffsetX) {
+              shadow._offsetY = length;
+              shadow._format.push(InlineEditor.CSSShadowModel._Part.OffsetY);
+            } else if (previousPart === InlineEditor.CSSShadowModel._Part.OffsetY) {
+              shadow._blurRadius = length;
+              shadow._format.push(InlineEditor.CSSShadowModel._Part.BlurRadius);
+            } else if (previousPart === InlineEditor.CSSShadowModel._Part.BlurRadius) {
+              shadow._spreadRadius = length;
+              shadow._format.push(InlineEditor.CSSShadowModel._Part.SpreadRadius);
+            } else {
+              shadow._offsetX = length;
+              shadow._format.push(InlineEditor.CSSShadowModel._Part.OffsetX);
+            }
+          }
+        }
+      }
+      if (invalidCount(InlineEditor.CSSShadowModel._Part.OffsetX, 1, 1) ||
+          invalidCount(InlineEditor.CSSShadowModel._Part.OffsetY, 1, 1) ||
+          invalidCount(InlineEditor.CSSShadowModel._Part.Color, 0, 1) ||
+          invalidCount(InlineEditor.CSSShadowModel._Part.BlurRadius, 0, 1) ||
+          invalidCount(InlineEditor.CSSShadowModel._Part.Inset, 0, isBoxShadow ? 1 : 0) ||
+          invalidCount(InlineEditor.CSSShadowModel._Part.SpreadRadius, 0, isBoxShadow ? 1 : 0))
+        return [];
+      shadows.push(shadow);
+    }
+    return shadows;
+
+    /**
+     * @param {string} part
+     * @param {number} min
+     * @param {number} max
+     * @return {boolean}
+     */
+    function invalidCount(part, min, max) {
+      var count = 0;
+      for (var i = 0; i < shadow._format.length; i++) {
+        if (shadow._format[i] === part)
+          count++;
+      }
+      return count < min || count > max;
+    }
+  }
+
+  /**
+   * @param {boolean} inset
+   */
+  setInset(inset) {
+    this._inset = inset;
+    if (this._format.indexOf(InlineEditor.CSSShadowModel._Part.Inset) === -1)
+      this._format.unshift(InlineEditor.CSSShadowModel._Part.Inset);
+  }
+
+  /**
+   * @param {!InlineEditor.CSSLength} offsetX
+   */
+  setOffsetX(offsetX) {
+    this._offsetX = offsetX;
+  }
+
+  /**
+   * @param {!InlineEditor.CSSLength} offsetY
+   */
+  setOffsetY(offsetY) {
+    this._offsetY = offsetY;
+  }
+
+  /**
+   * @param {!InlineEditor.CSSLength} blurRadius
+   */
+  setBlurRadius(blurRadius) {
+    this._blurRadius = blurRadius;
+    if (this._format.indexOf(InlineEditor.CSSShadowModel._Part.BlurRadius) === -1) {
+      var yIndex = this._format.indexOf(InlineEditor.CSSShadowModel._Part.OffsetY);
+      this._format.splice(yIndex + 1, 0, InlineEditor.CSSShadowModel._Part.BlurRadius);
+    }
+  }
+
+  /**
+   * @param {!InlineEditor.CSSLength} spreadRadius
+   */
+  setSpreadRadius(spreadRadius) {
+    this._spreadRadius = spreadRadius;
+    if (this._format.indexOf(InlineEditor.CSSShadowModel._Part.SpreadRadius) === -1) {
+      this.setBlurRadius(this._blurRadius);
+      var blurIndex = this._format.indexOf(InlineEditor.CSSShadowModel._Part.BlurRadius);
+      this._format.splice(blurIndex + 1, 0, InlineEditor.CSSShadowModel._Part.SpreadRadius);
+    }
+  }
+
+  /**
+   * @param {!Common.Color} color
+   */
+  setColor(color) {
+    this._color = color;
+    if (this._format.indexOf(InlineEditor.CSSShadowModel._Part.Color) === -1)
+      this._format.push(InlineEditor.CSSShadowModel._Part.Color);
+  }
+
+  /**
+   * @return {boolean}
+   */
+  isBoxShadow() {
+    return this._isBoxShadow;
+  }
+
+  /**
+   * @return {boolean}
+   */
+  inset() {
+    return this._inset;
+  }
+
+  /**
+   * @return {!InlineEditor.CSSLength}
+   */
+  offsetX() {
+    return this._offsetX;
+  }
+
+  /**
+   * @return {!InlineEditor.CSSLength}
+   */
+  offsetY() {
+    return this._offsetY;
+  }
+
+  /**
+   * @return {!InlineEditor.CSSLength}
+   */
+  blurRadius() {
+    return this._blurRadius;
+  }
+
+  /**
+   * @return {!InlineEditor.CSSLength}
+   */
+  spreadRadius() {
+    return this._spreadRadius;
+  }
+
+  /**
+   * @return {!Common.Color}
+   */
+  color() {
+    return this._color;
+  }
+
+  /**
+   * @return {string}
+   */
+  asCSSText() {
+    var parts = [];
+    for (var i = 0; i < this._format.length; i++) {
+      var part = this._format[i];
+      if (part === InlineEditor.CSSShadowModel._Part.Inset && this._inset)
+        parts.push('inset');
+      else if (part === InlineEditor.CSSShadowModel._Part.OffsetX)
+        parts.push(this._offsetX.asCSSText());
+      else if (part === InlineEditor.CSSShadowModel._Part.OffsetY)
+        parts.push(this._offsetY.asCSSText());
+      else if (part === InlineEditor.CSSShadowModel._Part.BlurRadius)
+        parts.push(this._blurRadius.asCSSText());
+      else if (part === InlineEditor.CSSShadowModel._Part.SpreadRadius)
+        parts.push(this._spreadRadius.asCSSText());
+      else if (part === InlineEditor.CSSShadowModel._Part.Color)
+        parts.push(this._color.asString(this._color.format()));
+    }
+    return parts.join(' ');
+  }
+};
+
+/**
+ * @enum {string}
+ */
+InlineEditor.CSSShadowModel._Part = {
+  Inset: 'I',
+  OffsetX: 'X',
+  OffsetY: 'Y',
+  BlurRadius: 'B',
+  SpreadRadius: 'S',
+  Color: 'C'
+};
+
+
+/**
+ * @unrestricted
+ */
+InlineEditor.CSSLength = class {
+  /**
+   * @param {number} amount
+   * @param {string} unit
+   */
+  constructor(amount, unit) {
+    this.amount = amount;
+    this.unit = unit;
+  }
+
+  /**
+   * @param {string} text
+   * @return {?InlineEditor.CSSLength}
+   */
+  static parse(text) {
+    var lengthRegex = new RegExp('^(?:' + InlineEditor.CSSLength.Regex.source + ')$', 'i');
+    var match = text.match(lengthRegex);
+    if (!match)
+      return null;
+    if (match.length > 2 && match[2])
+      return new InlineEditor.CSSLength(parseFloat(match[1]), match[2]);
+    return InlineEditor.CSSLength.zero();
+  }
+
+  /**
+   * @return {!InlineEditor.CSSLength}
+   */
+  static zero() {
+    return new InlineEditor.CSSLength(0, '');
+  }
+
+  /**
+   * @return {string}
+   */
+  asCSSText() {
+    return this.amount + this.unit;
+  }
+};
+
+/** @type {!RegExp} */
+InlineEditor.CSSLength.Regex = (function() {
+  var number = '([+-]?(?:[0-9]*[.])?[0-9]+(?:[eE][+-]?[0-9]+)?)';
+  var unit = '(ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmax|vmin|vw)';
+  var zero = '[+-]?(?:0*[.])?0+(?:[eE][+-]?[0-9]+)?';
+  return new RegExp(number + unit + '|' + zero, 'gi');
+})();
diff --git a/third_party/WebKit/Source/devtools/front_end/inline_editor/ColorSwatch.js b/third_party/WebKit/Source/devtools/front_end/inline_editor/ColorSwatch.js
index bb2831a..823d9d7 100644
--- a/third_party/WebKit/Source/devtools/front_end/inline_editor/ColorSwatch.js
+++ b/third_party/WebKit/Source/devtools/front_end/inline_editor/ColorSwatch.js
@@ -235,14 +235,14 @@
   }
 
   /**
-   * @return {!Common.CSSShadowModel} cssShadowModel
+   * @return {!InlineEditor.CSSShadowModel} cssShadowModel
    */
   model() {
     return this._model;
   }
 
   /**
-   * @param {!Common.CSSShadowModel} model
+   * @param {!InlineEditor.CSSShadowModel} model
    */
   setCSSShadow(model) {
     this._model = model;
diff --git a/third_party/WebKit/Source/devtools/front_end/inline_editor/module.json b/third_party/WebKit/Source/devtools/front_end/inline_editor/module.json
index ee1b6f2..b37b283 100644
--- a/third_party/WebKit/Source/devtools/front_end/inline_editor/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/inline_editor/module.json
@@ -7,7 +7,8 @@
         "BezierUI.js",
         "ColorSwatch.js",
         "CSSShadowEditor.js",
-        "SwatchPopoverHelper.js"
+        "SwatchPopoverHelper.js",
+        "CSSShadowModel.js"
     ],
     "resources": [
         "bezierEditor.css",
diff --git a/third_party/WebKit/Source/devtools/front_end/layer_viewer/Layers3DView.js b/third_party/WebKit/Source/devtools/front_end/layer_viewer/Layers3DView.js
index a872455..52f1fe9 100644
--- a/third_party/WebKit/Source/devtools/front_end/layer_viewer/Layers3DView.js
+++ b/third_party/WebKit/Source/devtools/front_end/layer_viewer/Layers3DView.js
@@ -265,7 +265,7 @@
 
     var bounds;
     for (var i = 0; i < this._rects.length; ++i)
-      bounds = Common.Geometry.boundsForTransformedPoints(scaleAndRotationMatrix, this._rects[i].vertices, bounds);
+      bounds = UI.Geometry.boundsForTransformedPoints(scaleAndRotationMatrix, this._rects[i].vertices, bounds);
 
     this._transformController.clampOffsets(
         (paddingX - bounds.maxX) / window.devicePixelRatio,
@@ -1106,12 +1106,12 @@
     // Vertices of the quad with transform matrix applied
     var points = [];
     for (i = 0; i < 4; ++i) {
-      points[i] = Common.Geometry.multiplyVectorByMatrixAndNormalize(
-          new Common.Geometry.Vector(this.vertices[i * 3], this.vertices[i * 3 + 1], this.vertices[i * 3 + 2]), matrix);
+      points[i] = UI.Geometry.multiplyVectorByMatrixAndNormalize(
+          new UI.Geometry.Vector(this.vertices[i * 3], this.vertices[i * 3 + 1], this.vertices[i * 3 + 2]), matrix);
     }
     // Calculating quad plane normal
-    var normal = Common.Geometry.crossProduct(
-        Common.Geometry.subtract(points[1], points[0]), Common.Geometry.subtract(points[2], points[1]));
+    var normal = UI.Geometry.crossProduct(
+        UI.Geometry.subtract(points[1], points[0]), UI.Geometry.subtract(points[2], points[1]));
     // General form of the equation of the quad plane: A * x + B * y + C * z + D = 0
     var A = normal.x;
     var B = normal.y;
@@ -1120,14 +1120,14 @@
     // Finding t from the equation
     var t = -(D + A * x0 + B * y0) / C;
     // Point of the intersection
-    var pt = new Common.Geometry.Vector(x0, y0, t);
+    var pt = new UI.Geometry.Vector(x0, y0, t);
     // Vectors from the intersection point to vertices of the quad
-    var tVects = points.map(Common.Geometry.subtract.bind(null, pt));
+    var tVects = points.map(UI.Geometry.subtract.bind(null, pt));
     // Intersection point lies inside of the polygon if scalar products of normal of the plane and
     // cross products of successive tVects are all nonstrictly above or all nonstrictly below zero
     for (i = 0; i < tVects.length; ++i) {
-      var product = Common.Geometry.scalarProduct(
-          normal, Common.Geometry.crossProduct(tVects[i], tVects[(i + 1) % tVects.length]));
+      var product =
+          UI.Geometry.scalarProduct(normal, UI.Geometry.crossProduct(tVects[i], tVects[(i + 1) % tVects.length]));
       if (product < 0)
         return undefined;
     }
diff --git a/third_party/WebKit/Source/devtools/front_end/layers/LayerTreeModel.js b/third_party/WebKit/Source/devtools/front_end/layers/LayerTreeModel.js
index e79eeab8..cb4cc7bd 100644
--- a/third_party/WebKit/Source/devtools/front_end/layers/LayerTreeModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/layers/LayerTreeModel.js
@@ -496,10 +496,10 @@
 
     if (this._layerPayload.transform) {
       var transformMatrix = this._matrixFromArray(this._layerPayload.transform);
-      var anchorVector = new Common.Geometry.Vector(
+      var anchorVector = new UI.Geometry.Vector(
           this._layerPayload.width * this.anchorPoint()[0], this._layerPayload.height * this.anchorPoint()[1],
           this.anchorPoint()[2]);
-      var anchorPoint = Common.Geometry.multiplyVectorByMatrixAndNormalize(anchorVector, matrix);
+      var anchorPoint = UI.Geometry.multiplyVectorByMatrixAndNormalize(anchorVector, matrix);
       var anchorMatrix = new WebKitCSSMatrix().translate(-anchorPoint.x, -anchorPoint.y, -anchorPoint.z);
       matrix = anchorMatrix.inverse().multiply(transformMatrix.multiply(anchorMatrix.multiply(matrix)));
     }
@@ -525,8 +525,8 @@
     this._quad = [];
     var vertices = this._createVertexArrayForRect(this._layerPayload.width, this._layerPayload.height);
     for (var i = 0; i < 4; ++i) {
-      var point = Common.Geometry.multiplyVectorByMatrixAndNormalize(
-          new Common.Geometry.Vector(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]), matrix);
+      var point = UI.Geometry.multiplyVectorByMatrixAndNormalize(
+          new UI.Geometry.Vector(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]), matrix);
       this._quad.push(point.x, point.y);
     }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/main/module.json b/third_party/WebKit/Source/devtools/front_end/main/module.json
index 4f608b4..df4d4435 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/main/module.json
@@ -433,10 +433,10 @@
         "RenderingOptions.js",
         "SimpleApp.js",
         "OverlayController.js",
-        "Main.js",
         "GCActionDelegate.js",
         "RequestAppBannerActionDelegate.js",
-        "ExecutionContextSelector.js"
+        "ExecutionContextSelector.js",
+        "Main.js"
     ],
     "resources": [
         "errorWarningCounter.css",
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/MemoryProfilerPanel.js b/third_party/WebKit/Source/devtools/front_end/profiler/MemoryProfilerPanel.js
new file mode 100644
index 0000000..7ac515c
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/MemoryProfilerPanel.js
@@ -0,0 +1,78 @@
+// 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.
+
+/**
+ * @implements {UI.ContextMenu.Provider}
+ * @implements {UI.ActionDelegate}
+ */
+Profiler.MemoryProfilerPanel = class extends Profiler.ProfilesPanel {
+  /**
+   * @override
+   * @param {!Event} event
+   * @param {!UI.ContextMenu} contextMenu
+   * @param {!Object} target
+   */
+  appendApplicableItems(event, contextMenu, target) {
+    if (!(target instanceof SDK.RemoteObject))
+      return;
+
+    if (!this.isShowing())
+      return;
+
+    var object = /** @type {!SDK.RemoteObject} */ (target);
+    var objectId = object.objectId;
+    if (!objectId)
+      return;
+
+    var heapProfiles = Profiler.ProfileTypeRegistry.instance.heapSnapshotProfileType.getProfiles();
+    if (!heapProfiles.length)
+      return;
+
+    /**
+     * @this {Profiler.ProfilesPanel}
+     */
+    function revealInView(viewName) {
+      object.target().heapProfilerAgent().getHeapObjectId(objectId, didReceiveHeapObjectId.bind(this, viewName));
+    }
+
+    /**
+     * @this {Profiler.ProfilesPanel}
+     */
+    function didReceiveHeapObjectId(viewName, error, result) {
+      if (!this.isShowing())
+        return;
+      if (!error)
+        this.showObject(result, viewName);
+    }
+
+    contextMenu.appendItem(Common.UIString.capitalize('Reveal in Summary ^view'), revealInView.bind(this, 'Summary'));
+  }
+
+  /**
+   * @override
+   * @param {!UI.Context} context
+   * @param {string} actionId
+   * @return {boolean}
+   */
+  handleAction(context, actionId) {
+    var panel = UI.context.flavor(Profiler.MemoryProfilerPanel);
+    console.assert(panel && panel instanceof Profiler.MemoryProfilerPanel);
+    panel.toggleRecord();
+    return true;
+  }
+
+  /**
+   * @override
+   */
+  wasShown() {
+    UI.context.setFlavor(Profiler.MemoryProfilerPanel, this);
+  }
+
+  /**
+   * @override
+   */
+  willHide() {
+    UI.context.setFlavor(Profiler.MemoryProfilerPanel, null);
+  }
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/ProfileHeader.js b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileHeader.js
new file mode 100644
index 0000000..a25d78c
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileHeader.js
@@ -0,0 +1,121 @@
+// 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.
+
+/**
+ * @unrestricted
+ */
+Profiler.ProfileHeader = class extends Common.Object {
+  /**
+   * @param {?SDK.Target} target
+   * @param {!Profiler.ProfileType} profileType
+   * @param {string} title
+   */
+  constructor(target, profileType, title) {
+    super();
+    this._target = target;
+    this._profileType = profileType;
+    this.title = title;
+    this.uid = profileType.incrementProfileUid();
+    this._fromFile = false;
+  }
+
+  /**
+   * @return {?SDK.Target}
+   */
+  target() {
+    return this._target;
+  }
+
+  /**
+   * @return {!Profiler.ProfileType}
+   */
+  profileType() {
+    return this._profileType;
+  }
+
+  /**
+   * @param {?string} subtitle
+   * @param {boolean=} wait
+   */
+  updateStatus(subtitle, wait) {
+    this.dispatchEventToListeners(
+        Profiler.ProfileHeader.Events.UpdateStatus, new Profiler.ProfileHeader.StatusUpdate(subtitle, wait));
+  }
+
+  /**
+   * Must be implemented by subclasses.
+   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
+   * @return {!Profiler.ProfileSidebarTreeElement}
+   */
+  createSidebarTreeElement(dataDisplayDelegate) {
+    throw new Error('Needs implemented.');
+  }
+
+  /**
+   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
+   * @return {!UI.Widget}
+   */
+  createView(dataDisplayDelegate) {
+    throw new Error('Not implemented.');
+  }
+
+  removeTempFile() {
+    if (this._tempFile)
+      this._tempFile.remove();
+  }
+
+  dispose() {
+  }
+
+  /**
+   * @return {boolean}
+   */
+  canSaveToFile() {
+    return false;
+  }
+
+  saveToFile() {
+    throw new Error('Needs implemented');
+  }
+
+  /**
+   * @param {!File} file
+   */
+  loadFromFile(file) {
+    throw new Error('Needs implemented');
+  }
+
+  /**
+   * @return {boolean}
+   */
+  fromFile() {
+    return this._fromFile;
+  }
+
+  setFromFile() {
+    this._fromFile = true;
+  }
+};
+
+/**
+ * @unrestricted
+ */
+Profiler.ProfileHeader.StatusUpdate = class {
+  /**
+   * @param {?string} subtitle
+   * @param {boolean|undefined} wait
+   */
+  constructor(subtitle, wait) {
+    /** @type {?string} */
+    this.subtitle = subtitle;
+    /** @type {boolean|undefined} */
+    this.wait = wait;
+  }
+};
+
+/** @enum {symbol} */
+Profiler.ProfileHeader.Events = {
+  UpdateStatus: Symbol('UpdateStatus'),
+  ProfileReceived: Symbol('ProfileReceived')
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/ProfileType.js b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileType.js
new file mode 100644
index 0000000..d8b6f75
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileType.js
@@ -0,0 +1,246 @@
+// 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.
+
+/**
+ * @unrestricted
+ */
+Profiler.ProfileType = class extends Common.Object {
+  /**
+   * @param {string} id
+   * @param {string} name
+   * @suppressGlobalPropertiesCheck
+   */
+  constructor(id, name) {
+    super();
+    this._id = id;
+    this._name = name;
+    /** @type {!Array.<!Profiler.ProfileHeader>} */
+    this._profiles = [];
+    /** @type {?Profiler.ProfileHeader} */
+    this._profileBeingRecorded = null;
+    this._nextProfileUid = 1;
+
+    if (!window.opener)
+      window.addEventListener('unload', this._clearTempStorage.bind(this), false);
+  }
+
+  /**
+   * @return {string}
+   */
+  typeName() {
+    return '';
+  }
+
+  /**
+   * @return {number}
+   */
+  nextProfileUid() {
+    return this._nextProfileUid;
+  }
+
+  /**
+   * @return {number}
+   */
+  incrementProfileUid() {
+    return this._nextProfileUid++;
+  }
+
+  /**
+   * @return {boolean}
+   */
+  hasTemporaryView() {
+    return false;
+  }
+
+  /**
+   * @return {?string}
+   */
+  fileExtension() {
+    return null;
+  }
+
+  get buttonTooltip() {
+    return '';
+  }
+
+  get id() {
+    return this._id;
+  }
+
+  get treeItemTitle() {
+    return this._name;
+  }
+
+  get name() {
+    return this._name;
+  }
+
+  /**
+   * @return {boolean}
+   */
+  buttonClicked() {
+    return false;
+  }
+
+  get description() {
+    return '';
+  }
+
+  /**
+   * @return {boolean}
+   */
+  isInstantProfile() {
+    return false;
+  }
+
+  /**
+   * @return {boolean}
+   */
+  isEnabled() {
+    return true;
+  }
+
+  /**
+   * @return {!Array.<!Profiler.ProfileHeader>}
+   */
+  getProfiles() {
+    /**
+     * @param {!Profiler.ProfileHeader} profile
+     * @return {boolean}
+     * @this {Profiler.ProfileType}
+     */
+    function isFinished(profile) {
+      return this._profileBeingRecorded !== profile;
+    }
+    return this._profiles.filter(isFinished.bind(this));
+  }
+
+  /**
+   * @return {?Element}
+   */
+  decorationElement() {
+    return null;
+  }
+
+  /**
+   * @param {number} uid
+   * @return {?Profiler.ProfileHeader}
+   */
+  getProfile(uid) {
+    for (var i = 0; i < this._profiles.length; ++i) {
+      if (this._profiles[i].uid === uid)
+        return this._profiles[i];
+    }
+    return null;
+  }
+
+  /**
+   * @param {!File} file
+   */
+  loadFromFile(file) {
+    var name = file.name;
+    var fileExtension = this.fileExtension();
+    if (fileExtension && name.endsWith(fileExtension))
+      name = name.substr(0, name.length - fileExtension.length);
+    var profile = this.createProfileLoadedFromFile(name);
+    profile.setFromFile();
+    this.setProfileBeingRecorded(profile);
+    this.addProfile(profile);
+    profile.loadFromFile(file);
+  }
+
+  /**
+   * @param {string} title
+   * @return {!Profiler.ProfileHeader}
+   */
+  createProfileLoadedFromFile(title) {
+    throw new Error('Needs implemented.');
+  }
+
+  /**
+   * @param {!Profiler.ProfileHeader} profile
+   */
+  addProfile(profile) {
+    this._profiles.push(profile);
+    this.dispatchEventToListeners(Profiler.ProfileType.Events.AddProfileHeader, profile);
+  }
+
+  /**
+   * @param {!Profiler.ProfileHeader} profile
+   */
+  removeProfile(profile) {
+    var index = this._profiles.indexOf(profile);
+    if (index === -1)
+      return;
+    this._profiles.splice(index, 1);
+    this._disposeProfile(profile);
+  }
+
+  _clearTempStorage() {
+    for (var i = 0; i < this._profiles.length; ++i)
+      this._profiles[i].removeTempFile();
+  }
+
+  /**
+   * @return {?Profiler.ProfileHeader}
+   */
+  profileBeingRecorded() {
+    return this._profileBeingRecorded;
+  }
+
+  /**
+   * @param {?Profiler.ProfileHeader} profile
+   */
+  setProfileBeingRecorded(profile) {
+    this._profileBeingRecorded = profile;
+  }
+
+  profileBeingRecordedRemoved() {
+  }
+
+  reset() {
+    this._profiles.slice(0).forEach(this._disposeProfile.bind(this));
+    this._profiles = [];
+    this._nextProfileUid = 1;
+  }
+
+  /**
+   * @param {!Profiler.ProfileHeader} profile
+   */
+  _disposeProfile(profile) {
+    this.dispatchEventToListeners(Profiler.ProfileType.Events.RemoveProfileHeader, profile);
+    profile.dispose();
+    if (this._profileBeingRecorded === profile) {
+      this.profileBeingRecordedRemoved();
+      this.setProfileBeingRecorded(null);
+    }
+  }
+};
+
+/** @enum {symbol} */
+Profiler.ProfileType.Events = {
+  AddProfileHeader: Symbol('add-profile-header'),
+  ProfileComplete: Symbol('profile-complete'),
+  RemoveProfileHeader: Symbol('remove-profile-header'),
+  ViewUpdated: Symbol('view-updated')
+};
+
+/**
+ * @interface
+ */
+Profiler.ProfileType.DataDisplayDelegate = function() {};
+
+Profiler.ProfileType.DataDisplayDelegate.prototype = {
+  /**
+   * @param {?Profiler.ProfileHeader} profile
+   * @return {?UI.Widget}
+   */
+  showProfile(profile) {},
+
+  /**
+   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
+   * @param {string} perspectiveName
+   */
+  showObject(snapshotObjectId, perspectiveName) {}
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js b/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
index 1bf9115..86786b8 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
@@ -24,360 +24,6 @@
  */
 
 /**
- * @unrestricted
- */
-Profiler.ProfileType = class extends Common.Object {
-  /**
-   * @param {string} id
-   * @param {string} name
-   * @suppressGlobalPropertiesCheck
-   */
-  constructor(id, name) {
-    super();
-    this._id = id;
-    this._name = name;
-    /** @type {!Array.<!Profiler.ProfileHeader>} */
-    this._profiles = [];
-    /** @type {?Profiler.ProfileHeader} */
-    this._profileBeingRecorded = null;
-    this._nextProfileUid = 1;
-
-    if (!window.opener)
-      window.addEventListener('unload', this._clearTempStorage.bind(this), false);
-  }
-
-  /**
-   * @return {string}
-   */
-  typeName() {
-    return '';
-  }
-
-  /**
-   * @return {number}
-   */
-  nextProfileUid() {
-    return this._nextProfileUid;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  hasTemporaryView() {
-    return false;
-  }
-
-  /**
-   * @return {?string}
-   */
-  fileExtension() {
-    return null;
-  }
-
-  get buttonTooltip() {
-    return '';
-  }
-
-  get id() {
-    return this._id;
-  }
-
-  get treeItemTitle() {
-    return this._name;
-  }
-
-  get name() {
-    return this._name;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  buttonClicked() {
-    return false;
-  }
-
-  get description() {
-    return '';
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isInstantProfile() {
-    return false;
-  }
-
-  /**
-   * @return {boolean}
-   */
-  isEnabled() {
-    return true;
-  }
-
-  /**
-   * @return {!Array.<!Profiler.ProfileHeader>}
-   */
-  getProfiles() {
-    /**
-     * @param {!Profiler.ProfileHeader} profile
-     * @return {boolean}
-     * @this {Profiler.ProfileType}
-     */
-    function isFinished(profile) {
-      return this._profileBeingRecorded !== profile;
-    }
-    return this._profiles.filter(isFinished.bind(this));
-  }
-
-  /**
-   * @return {?Element}
-   */
-  decorationElement() {
-    return null;
-  }
-
-  /**
-   * @param {number} uid
-   * @return {?Profiler.ProfileHeader}
-   */
-  getProfile(uid) {
-    for (var i = 0; i < this._profiles.length; ++i) {
-      if (this._profiles[i].uid === uid)
-        return this._profiles[i];
-    }
-    return null;
-  }
-
-  /**
-   * @param {!File} file
-   */
-  loadFromFile(file) {
-    var name = file.name;
-    var fileExtension = this.fileExtension();
-    if (fileExtension && name.endsWith(fileExtension))
-      name = name.substr(0, name.length - fileExtension.length);
-    var profile = this.createProfileLoadedFromFile(name);
-    profile.setFromFile();
-    this.setProfileBeingRecorded(profile);
-    this.addProfile(profile);
-    profile.loadFromFile(file);
-  }
-
-  /**
-   * @param {string} title
-   * @return {!Profiler.ProfileHeader}
-   */
-  createProfileLoadedFromFile(title) {
-    throw new Error('Needs implemented.');
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   */
-  addProfile(profile) {
-    this._profiles.push(profile);
-    this.dispatchEventToListeners(Profiler.ProfileType.Events.AddProfileHeader, profile);
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   */
-  removeProfile(profile) {
-    var index = this._profiles.indexOf(profile);
-    if (index === -1)
-      return;
-    this._profiles.splice(index, 1);
-    this._disposeProfile(profile);
-  }
-
-  _clearTempStorage() {
-    for (var i = 0; i < this._profiles.length; ++i)
-      this._profiles[i].removeTempFile();
-  }
-
-  /**
-   * @return {?Profiler.ProfileHeader}
-   */
-  profileBeingRecorded() {
-    return this._profileBeingRecorded;
-  }
-
-  /**
-   * @param {?Profiler.ProfileHeader} profile
-   */
-  setProfileBeingRecorded(profile) {
-    this._profileBeingRecorded = profile;
-  }
-
-  profileBeingRecordedRemoved() {
-  }
-
-  reset() {
-    this._profiles.slice(0).forEach(this._disposeProfile.bind(this));
-    this._profiles = [];
-    this._nextProfileUid = 1;
-  }
-
-  /**
-   * @param {!Profiler.ProfileHeader} profile
-   */
-  _disposeProfile(profile) {
-    this.dispatchEventToListeners(Profiler.ProfileType.Events.RemoveProfileHeader, profile);
-    profile.dispose();
-    if (this._profileBeingRecorded === profile) {
-      this.profileBeingRecordedRemoved();
-      this.setProfileBeingRecorded(null);
-    }
-  }
-};
-
-/** @enum {symbol} */
-Profiler.ProfileType.Events = {
-  AddProfileHeader: Symbol('add-profile-header'),
-  ProfileComplete: Symbol('profile-complete'),
-  RemoveProfileHeader: Symbol('remove-profile-header'),
-  ViewUpdated: Symbol('view-updated')
-};
-
-/**
- * @interface
- */
-Profiler.ProfileType.DataDisplayDelegate = function() {};
-
-Profiler.ProfileType.DataDisplayDelegate.prototype = {
-  /**
-   * @param {?Profiler.ProfileHeader} profile
-   * @return {?UI.Widget}
-   */
-  showProfile(profile) {},
-
-  /**
-   * @param {!Protocol.HeapProfiler.HeapSnapshotObjectId} snapshotObjectId
-   * @param {string} perspectiveName
-   */
-  showObject(snapshotObjectId, perspectiveName) {}
-};
-
-/**
- * @unrestricted
- */
-Profiler.ProfileHeader = class extends Common.Object {
-  /**
-   * @param {?SDK.Target} target
-   * @param {!Profiler.ProfileType} profileType
-   * @param {string} title
-   */
-  constructor(target, profileType, title) {
-    super();
-    this._target = target;
-    this._profileType = profileType;
-    this.title = title;
-    this.uid = profileType._nextProfileUid++;
-    this._fromFile = false;
-  }
-
-  /**
-   * @return {?SDK.Target}
-   */
-  target() {
-    return this._target;
-  }
-
-  /**
-   * @return {!Profiler.ProfileType}
-   */
-  profileType() {
-    return this._profileType;
-  }
-
-  /**
-   * @param {?string} subtitle
-   * @param {boolean=} wait
-   */
-  updateStatus(subtitle, wait) {
-    this.dispatchEventToListeners(
-        Profiler.ProfileHeader.Events.UpdateStatus, new Profiler.ProfileHeader.StatusUpdate(subtitle, wait));
-  }
-
-  /**
-   * Must be implemented by subclasses.
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @return {!Profiler.ProfileSidebarTreeElement}
-   */
-  createSidebarTreeElement(dataDisplayDelegate) {
-    throw new Error('Needs implemented.');
-  }
-
-  /**
-   * @param {!Profiler.ProfileType.DataDisplayDelegate} dataDisplayDelegate
-   * @return {!UI.Widget}
-   */
-  createView(dataDisplayDelegate) {
-    throw new Error('Not implemented.');
-  }
-
-  removeTempFile() {
-    if (this._tempFile)
-      this._tempFile.remove();
-  }
-
-  dispose() {
-  }
-
-  /**
-   * @return {boolean}
-   */
-  canSaveToFile() {
-    return false;
-  }
-
-  saveToFile() {
-    throw new Error('Needs implemented');
-  }
-
-  /**
-   * @param {!File} file
-   */
-  loadFromFile(file) {
-    throw new Error('Needs implemented');
-  }
-
-  /**
-   * @return {boolean}
-   */
-  fromFile() {
-    return this._fromFile;
-  }
-
-  setFromFile() {
-    this._fromFile = true;
-  }
-};
-
-/**
- * @unrestricted
- */
-Profiler.ProfileHeader.StatusUpdate = class {
-  /**
-   * @param {?string} subtitle
-   * @param {boolean|undefined} wait
-   */
-  constructor(subtitle, wait) {
-    /** @type {?string} */
-    this.subtitle = subtitle;
-    /** @type {boolean|undefined} */
-    this.wait = wait;
-  }
-};
-
-/** @enum {symbol} */
-Profiler.ProfileHeader.Events = {
-  UpdateStatus: Symbol('UpdateStatus'),
-  ProfileReceived: Symbol('ProfileReceived')
-};
-
-/**
  * @implements {Profiler.ProfileType.DataDisplayDelegate}
  * @unrestricted
  */
@@ -688,7 +334,7 @@
    * @param {!Profiler.ProfileHeader} profile
    */
   _removeProfileHeader(profile) {
-    if (profile.profileType()._profileBeingRecorded === profile)
+    if (profile.profileType().profileBeingRecorded() === profile)
       this._profileBeingRecordedRemoved();
 
     var i = this._indexOfViewForProfile(profile);
@@ -793,66 +439,11 @@
   }
 
   /**
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    if (!(target instanceof SDK.RemoteObject))
-      return;
-
-    if (!this.isShowing())
-      return;
-
-    var object = /** @type {!SDK.RemoteObject} */ (target);
-    var objectId = object.objectId;
-    if (!objectId)
-      return;
-
-    var heapProfiles = Profiler.ProfileTypeRegistry.instance.heapSnapshotProfileType.getProfiles();
-    if (!heapProfiles.length)
-      return;
-
-    /**
-     * @this {Profiler.ProfilesPanel}
-     */
-    function revealInView(viewName) {
-      object.target().heapProfilerAgent().getHeapObjectId(objectId, didReceiveHeapObjectId.bind(this, viewName));
-    }
-
-    /**
-     * @this {Profiler.ProfilesPanel}
-     */
-    function didReceiveHeapObjectId(viewName, error, result) {
-      if (!this.isShowing())
-        return;
-      if (!error)
-        this.showObject(result, viewName);
-    }
-
-    contextMenu.appendItem(Common.UIString.capitalize('Reveal in Summary ^view'), revealInView.bind(this, 'Summary'));
-  }
-
-  /**
-   * @override
-   */
-  wasShown() {
-    UI.context.setFlavor(Profiler.ProfilesPanel, this);
-  }
-
-  /**
    * @override
    */
   focus() {
     this._sidebarTree.focus();
   }
-
-  /**
-   * @override
-   */
-  willHide() {
-    UI.context.setFlavor(Profiler.ProfilesPanel, null);
-  }
 };
 
 /**
@@ -1009,22 +600,6 @@
 };
 
 /**
- * @implements {UI.ContextMenu.Provider}
- * @unrestricted
- */
-Profiler.ProfilesPanel.ContextMenuProvider = class {
-  /**
-   * @override
-   * @param {!Event} event
-   * @param {!UI.ContextMenu} contextMenu
-   * @param {!Object} target
-   */
-  appendApplicableItems(event, contextMenu, target) {
-    Profiler.ProfilesPanel._instance().appendApplicableItems(event, contextMenu, target);
-  }
-};
-
-/**
  * @unrestricted
  */
 Profiler.ProfileSidebarTreeElement = class extends UI.TreeElement {
@@ -1220,21 +795,3 @@
         .textContent = Common.UIString('Profiles');
   }
 };
-
-/**
- * @implements {UI.ActionDelegate}
- */
-Profiler.ProfilesPanel.RecordActionDelegate = class {
-  /**
-   * @override
-   * @param {!UI.Context} context
-   * @param {string} actionId
-   * @return {boolean}
-   */
-  handleAction(context, actionId) {
-    var panel = UI.context.flavor(Profiler.ProfilesPanel);
-    console.assert(panel && panel instanceof Profiler.ProfilesPanel);
-    panel.toggleRecord();
-    return true;
-  }
-};
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/module.json b/third_party/WebKit/Source/devtools/front_end/profiler/module.json
index a980c23..c5abce3 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/module.json
@@ -15,7 +15,7 @@
             "id": "profiles",
             "title": "Memory",
             "order": 60,
-            "className": "Profiler.ProfilesPanel",
+            "className": "Profiler.MemoryProfilerPanel",
             "condition": "!v8only"
         },
         {
@@ -23,7 +23,7 @@
             "contextTypes": [
                 "SDK.RemoteObject"
             ],
-            "className": "Profiler.ProfilesPanel.ContextMenuProvider"
+            "className": "Profiler.MemoryProfilerPanel"
         },
         {
             "type": "setting",
@@ -56,9 +56,9 @@
             "toggledIconClass": "largeicon-stop-recording",
             "toggleWithRedColor": true,
             "contextTypes": [
-                "Profiler.ProfilesPanel"
+                "Profiler.MemoryProfilerPanel"
             ],
-            "className": "Profiler.ProfilesPanel.RecordActionDelegate",
+            "className": "Profiler.MemoryProfilerPanel",
             "bindings": [
                 {
                     "platform": "windows,linux",
@@ -78,6 +78,8 @@
         "heap_snapshot_model"
     ],
     "scripts": [
+        "ProfileType.js",
+        "ProfileHeader.js",
         "ProfilesPanel.js",
         "ProfileView.js",
         "ProfileDataGrid.js",
@@ -90,6 +92,7 @@
         "HeapSnapshotDataGrids.js",
         "HeapSnapshotGridNodes.js",
         "HeapSnapshotView.js",
+        "MemoryProfilerPanel.js",
         "ProfileLauncherView.js",
         "ProfileTypeRegistry.js",
         "TargetsComboBoxController.js"
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
index 78b5bc33..8fa80f7c 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
@@ -498,10 +498,11 @@
   Rendering: 'rendering',
   CSS: 'css',
   Security: 'security',
-  Violation: 'violation',
-  Other: 'other',
   Deprecation: 'deprecation',
-  Worker: 'worker'
+  Worker: 'worker',
+  Violation: 'violation',
+  Intervention: 'intervention',
+  Other: 'other'
 };
 
 /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/CSSSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/CSSSourceFrame.js
index bd6c81e..4e5adf1 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/CSSSourceFrame.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/CSSSourceFrame.js
@@ -110,12 +110,11 @@
     var swatches = [];
     var swatchPositions = [];
 
-    var regexes = [
-      SDK.CSSMetadata.VariableRegex, SDK.CSSMetadata.URLRegex, Common.Geometry.CubicBezier.Regex, Common.Color.Regex
-    ];
+    var regexes =
+        [SDK.CSSMetadata.VariableRegex, SDK.CSSMetadata.URLRegex, UI.Geometry.CubicBezier.Regex, Common.Color.Regex];
     var handlers = new Map();
     handlers.set(Common.Color.Regex, this._createColorSwatch.bind(this));
-    handlers.set(Common.Geometry.CubicBezier.Regex, this._createBezierSwatch.bind(this));
+    handlers.set(UI.Geometry.CubicBezier.Regex, this._createBezierSwatch.bind(this));
 
     for (var lineNumber = startLine; lineNumber <= endLine; lineNumber++) {
       var line = this.textEditor.line(lineNumber).substring(0, Sources.CSSSourceFrame.maxSwatchProcessingLength);
@@ -177,7 +176,7 @@
    * @return {?InlineEditor.BezierSwatch}
    */
   _createBezierSwatch(text) {
-    if (!Common.Geometry.CubicBezier.parse(text))
+    if (!UI.Geometry.CubicBezier.parse(text))
       return null;
     var swatch = InlineEditor.BezierSwatch.create();
     swatch.setBezierText(text);
@@ -247,10 +246,10 @@
       this._bezierEditor = new InlineEditor.BezierEditor();
       this._bezierEditor.addEventListener(InlineEditor.BezierEditor.Events.BezierChanged, this._bezierChanged, this);
     }
-    var cubicBezier = Common.Geometry.CubicBezier.parse(swatch.bezierText());
+    var cubicBezier = UI.Geometry.CubicBezier.parse(swatch.bezierText());
     if (!cubicBezier) {
       cubicBezier =
-          /** @type {!Common.Geometry.CubicBezier} */ (Common.Geometry.CubicBezier.parse('linear'));
+          /** @type {!UI.Geometry.CubicBezier} */ (UI.Geometry.CubicBezier.parse('linear'));
     }
     this._bezierEditor.setBezier(cubicBezier);
     this._swatchPopoverHelper.show(this._bezierEditor, swatch.iconElement(), this._swatchPopoverHidden.bind(this));
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePaintProfilerView.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePaintProfilerView.js
index 23810c4..3b28a01 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePaintProfilerView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePaintProfilerView.js
@@ -193,7 +193,7 @@
                      .translate(clientWidth / 2, clientHeight / 2)
                      .scale(scale, scale)
                      .translate(-width / 2, -height / 2);
-    var bounds = Common.Geometry.boundsForTransformedPoints(matrix, [0, 0, 0, width, height, 0]);
+    var bounds = UI.Geometry.boundsForTransformedPoints(matrix, [0, 0, 0, width, height, 0]);
     this._transformController.clampOffsets(
         paddingX - bounds.maxX, clientWidth - paddingX - bounds.minX, paddingY - bounds.maxY,
         clientHeight - paddingY - bounds.minY);
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js b/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js
index cdce803..f4379fb 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js
@@ -130,7 +130,7 @@
   }
 
   /**
-   * @param {!Size} size
+   * @param {!UI.Size} size
    */
   setMaxSize(size) {
     this._maxSize = size;
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Geometry.js b/third_party/WebKit/Source/devtools/front_end/ui/Geometry.js
similarity index 60%
rename from third_party/WebKit/Source/devtools/front_end/common/Geometry.js
rename to third_party/WebKit/Source/devtools/front_end/ui/Geometry.js
index b90b92bb..f6e0f5b 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/Geometry.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/Geometry.js
@@ -27,17 +27,17 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-Common.Geometry = {};
+UI.Geometry = {};
 
 /**
  * @type {number}
  */
-Common.Geometry._Eps = 1e-5;
+UI.Geometry._Eps = 1e-5;
 
 /**
  * @unrestricted
  */
-Common.Geometry.Vector = class {
+UI.Geometry.Vector = class {
   /**
    * @param {number} x
    * @param {number} y
@@ -58,7 +58,7 @@
 
   normalize() {
     var length = this.length();
-    if (length <= Common.Geometry._Eps)
+    if (length <= UI.Geometry._Eps)
       return;
 
     this.x /= length;
@@ -70,7 +70,7 @@
 /**
  * @unrestricted
  */
-Common.Geometry.Point = class {
+UI.Geometry.Point = class {
   /**
    * @param {number} x
    * @param {number} y
@@ -81,7 +81,7 @@
   }
 
   /**
-   * @param {!Common.Geometry.Point} p
+   * @param {!UI.Geometry.Point} p
    * @return {number}
    */
   distanceTo(p) {
@@ -89,21 +89,21 @@
   }
 
   /**
-   * @param {!Common.Geometry.Point} line
-   * @return {!Common.Geometry.Point}
+   * @param {!UI.Geometry.Point} line
+   * @return {!UI.Geometry.Point}
    */
   projectOn(line) {
     if (line.x === 0 && line.y === 0)
-      return new Common.Geometry.Point(0, 0);
+      return new UI.Geometry.Point(0, 0);
     return line.scale((this.x * line.x + this.y * line.y) / (Math.pow(line.x, 2) + Math.pow(line.y, 2)));
   }
 
   /**
    * @param {number} scalar
-   * @return {!Common.Geometry.Point}
+   * @return {!UI.Geometry.Point}
    */
   scale(scalar) {
-    return new Common.Geometry.Point(this.x * scalar, this.y * scalar);
+    return new UI.Geometry.Point(this.x * scalar, this.y * scalar);
   }
 
   /**
@@ -118,10 +118,10 @@
 /**
  * @unrestricted
  */
-Common.Geometry.CubicBezier = class {
+UI.Geometry.CubicBezier = class {
   /**
-   * @param {!Common.Geometry.Point} point1
-   * @param {!Common.Geometry.Point} point2
+   * @param {!UI.Geometry.Point} point1
+   * @param {!UI.Geometry.Point} point2
    */
   constructor(point1, point2) {
     this.controlPoints = [point1, point2];
@@ -129,26 +129,26 @@
 
   /**
    * @param {string} text
-   * @return {?Common.Geometry.CubicBezier}
+   * @return {?UI.Geometry.CubicBezier}
    */
   static parse(text) {
-    var keywordValues = Common.Geometry.CubicBezier.KeywordValues;
+    var keywordValues = UI.Geometry.CubicBezier.KeywordValues;
     var value = text.toLowerCase().replace(/\s+/g, '');
     if (Object.keys(keywordValues).indexOf(value) !== -1)
-      return Common.Geometry.CubicBezier.parse(keywordValues[value]);
+      return UI.Geometry.CubicBezier.parse(keywordValues[value]);
     var bezierRegex = /^cubic-bezier\(([^,]+),([^,]+),([^,]+),([^,]+)\)$/;
     var match = value.match(bezierRegex);
     if (match) {
-      var control1 = new Common.Geometry.Point(parseFloat(match[1]), parseFloat(match[2]));
-      var control2 = new Common.Geometry.Point(parseFloat(match[3]), parseFloat(match[4]));
-      return new Common.Geometry.CubicBezier(control1, control2);
+      var control1 = new UI.Geometry.Point(parseFloat(match[1]), parseFloat(match[2]));
+      var control2 = new UI.Geometry.Point(parseFloat(match[3]), parseFloat(match[4]));
+      return new UI.Geometry.CubicBezier(control1, control2);
     }
     return null;
   }
 
   /**
    * @param {number} t
-   * @return {!Common.Geometry.Point}
+   * @return {!UI.Geometry.Point}
    */
   evaluateAt(t) {
     /**
@@ -162,7 +162,7 @@
 
     var x = evaluate(this.controlPoints[0].x, this.controlPoints[1].x, t);
     var y = evaluate(this.controlPoints[0].y, this.controlPoints[1].y, t);
-    return new Common.Geometry.Point(x, y);
+    return new UI.Geometry.Point(x, y);
   }
 
   /**
@@ -170,7 +170,7 @@
    */
   asCSSText() {
     var raw = 'cubic-bezier(' + this.controlPoints.join(', ') + ')';
-    var keywordValues = Common.Geometry.CubicBezier.KeywordValues;
+    var keywordValues = UI.Geometry.CubicBezier.KeywordValues;
     for (var keyword in keywordValues) {
       if (raw === keywordValues[keyword])
         return keyword;
@@ -180,9 +180,9 @@
 };
 
 /** @type {!RegExp} */
-Common.Geometry.CubicBezier.Regex = /((cubic-bezier\([^)]+\))|\b(linear|ease-in-out|ease-in|ease-out|ease)\b)/g;
+UI.Geometry.CubicBezier.Regex = /((cubic-bezier\([^)]+\))|\b(linear|ease-in-out|ease-in|ease-out|ease)\b)/g;
 
-Common.Geometry.CubicBezier.KeywordValues = {
+UI.Geometry.CubicBezier.KeywordValues = {
   'linear': 'cubic-bezier(0, 0, 1, 1)',
   'ease': 'cubic-bezier(0.25, 0.1, 0.25, 1)',
   'ease-in': 'cubic-bezier(0.42, 0, 1, 1)',
@@ -194,7 +194,7 @@
 /**
  * @unrestricted
  */
-Common.Geometry.EulerAngles = class {
+UI.Geometry.EulerAngles = class {
   /**
    * @param {number} alpha
    * @param {number} beta
@@ -208,7 +208,7 @@
 
   /**
    * @param {!CSSMatrix} rotationMatrix
-   * @return {!Common.Geometry.EulerAngles}
+   * @return {!UI.Geometry.EulerAngles}
    */
   static fromRotationMatrix(rotationMatrix) {
     var beta = Math.atan2(rotationMatrix.m23, rotationMatrix.m33);
@@ -216,17 +216,16 @@
         -rotationMatrix.m13,
         Math.sqrt(rotationMatrix.m11 * rotationMatrix.m11 + rotationMatrix.m12 * rotationMatrix.m12));
     var alpha = Math.atan2(rotationMatrix.m12, rotationMatrix.m11);
-    return new Common.Geometry.EulerAngles(
-        Common.Geometry.radiansToDegrees(alpha), Common.Geometry.radiansToDegrees(beta),
-        Common.Geometry.radiansToDegrees(gamma));
+    return new UI.Geometry.EulerAngles(
+        UI.Geometry.radiansToDegrees(alpha), UI.Geometry.radiansToDegrees(beta), UI.Geometry.radiansToDegrees(gamma));
   }
 
   /**
    * @return {string}
    */
   toRotate3DString() {
-    var gammaAxisY = -Math.sin(Common.Geometry.degreesToRadians(this.beta));
-    var gammaAxisZ = Math.cos(Common.Geometry.degreesToRadians(this.beta));
+    var gammaAxisY = -Math.sin(UI.Geometry.degreesToRadians(this.beta));
+    var gammaAxisZ = Math.cos(UI.Geometry.degreesToRadians(this.beta));
     var axis = {alpha: [0, 1, 0], beta: [-1, 0, 0], gamma: [0, gammaAxisY, gammaAxisZ]};
     return 'rotate3d(' + axis.alpha.join(',') + ',' + this.alpha + 'deg) ' +
         'rotate3d(' + axis.beta.join(',') + ',' + this.beta + 'deg) ' +
@@ -236,72 +235,72 @@
 
 
 /**
- * @param {!Common.Geometry.Vector} u
- * @param {!Common.Geometry.Vector} v
+ * @param {!UI.Geometry.Vector} u
+ * @param {!UI.Geometry.Vector} v
  * @return {number}
  */
-Common.Geometry.scalarProduct = function(u, v) {
+UI.Geometry.scalarProduct = function(u, v) {
   return u.x * v.x + u.y * v.y + u.z * v.z;
 };
 
 /**
- * @param {!Common.Geometry.Vector} u
- * @param {!Common.Geometry.Vector} v
- * @return {!Common.Geometry.Vector}
+ * @param {!UI.Geometry.Vector} u
+ * @param {!UI.Geometry.Vector} v
+ * @return {!UI.Geometry.Vector}
  */
-Common.Geometry.crossProduct = function(u, v) {
+UI.Geometry.crossProduct = function(u, v) {
   var x = u.y * v.z - u.z * v.y;
   var y = u.z * v.x - u.x * v.z;
   var z = u.x * v.y - u.y * v.x;
-  return new Common.Geometry.Vector(x, y, z);
+  return new UI.Geometry.Vector(x, y, z);
 };
 
 /**
- * @param {!Common.Geometry.Vector} u
- * @param {!Common.Geometry.Vector} v
- * @return {!Common.Geometry.Vector}
+ * @param {!UI.Geometry.Vector} u
+ * @param {!UI.Geometry.Vector} v
+ * @return {!UI.Geometry.Vector}
  */
-Common.Geometry.subtract = function(u, v) {
+UI.Geometry.subtract = function(u, v) {
   var x = u.x - v.x;
   var y = u.y - v.y;
   var z = u.z - v.z;
-  return new Common.Geometry.Vector(x, y, z);
+  return new UI.Geometry.Vector(x, y, z);
 };
 
 /**
- * @param {!Common.Geometry.Vector} v
+ * @param {!UI.Geometry.Vector} v
  * @param {!CSSMatrix} m
- * @return {!Common.Geometry.Vector}
+ * @return {!UI.Geometry.Vector}
  */
-Common.Geometry.multiplyVectorByMatrixAndNormalize = function(v, m) {
+UI.Geometry.multiplyVectorByMatrixAndNormalize = function(v, m) {
   var t = v.x * m.m14 + v.y * m.m24 + v.z * m.m34 + m.m44;
   var x = (v.x * m.m11 + v.y * m.m21 + v.z * m.m31 + m.m41) / t;
   var y = (v.x * m.m12 + v.y * m.m22 + v.z * m.m32 + m.m42) / t;
   var z = (v.x * m.m13 + v.y * m.m23 + v.z * m.m33 + m.m43) / t;
-  return new Common.Geometry.Vector(x, y, z);
+  return new UI.Geometry.Vector(x, y, z);
 };
 
 /**
- * @param {!Common.Geometry.Vector} u
- * @param {!Common.Geometry.Vector} v
+ * @param {!UI.Geometry.Vector} u
+ * @param {!UI.Geometry.Vector} v
  * @return {number}
  */
-Common.Geometry.calculateAngle = function(u, v) {
+UI.Geometry.calculateAngle = function(u, v) {
   var uLength = u.length();
   var vLength = v.length();
-  if (uLength <= Common.Geometry._Eps || vLength <= Common.Geometry._Eps)
+  if (uLength <= UI.Geometry._Eps || vLength <= UI.Geometry._Eps)
     return 0;
-  var cos = Common.Geometry.scalarProduct(u, v) / uLength / vLength;
+  var cos = UI.Geometry.scalarProduct(u, v) / uLength / vLength;
   if (Math.abs(cos) > 1)
     return 0;
-  return Common.Geometry.radiansToDegrees(Math.acos(cos));
+  return UI.Geometry.radiansToDegrees(Math.acos(cos));
 };
 
 /**
  * @param {number} deg
  * @return {number}
  */
-Common.Geometry.degreesToRadians = function(deg) {
+UI.Geometry.degreesToRadians = function(deg) {
   return deg * Math.PI / 180;
 };
 
@@ -309,7 +308,7 @@
  * @param {number} rad
  * @return {number}
  */
-Common.Geometry.radiansToDegrees = function(rad) {
+UI.Geometry.radiansToDegrees = function(rad) {
   return rad * 180 / Math.PI;
 };
 
@@ -319,14 +318,14 @@
  * @param {{minX: number, maxX: number, minY: number, maxY: number}=} aggregateBounds
  * @return {!{minX: number, maxX: number, minY: number, maxY: number}}
  */
-Common.Geometry.boundsForTransformedPoints = function(matrix, points, aggregateBounds) {
+UI.Geometry.boundsForTransformedPoints = function(matrix, points, aggregateBounds) {
   if (!aggregateBounds)
     aggregateBounds = {minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity};
   if (points.length % 3)
     console.assert('Invalid size of points array');
   for (var p = 0; p < points.length; p += 3) {
-    var vector = new Common.Geometry.Vector(points[p], points[p + 1], points[p + 2]);
-    vector = Common.Geometry.multiplyVectorByMatrixAndNormalize(vector, matrix);
+    var vector = new UI.Geometry.Vector(points[p], points[p + 1], points[p + 2]);
+    vector = UI.Geometry.multiplyVectorByMatrixAndNormalize(vector, matrix);
     aggregateBounds.minX = Math.min(aggregateBounds.minX, vector.x);
     aggregateBounds.maxX = Math.max(aggregateBounds.maxX, vector.x);
     aggregateBounds.minY = Math.min(aggregateBounds.minY, vector.y);
@@ -338,7 +337,7 @@
 /**
  * @unrestricted
  */
-var Size = class {
+UI.Size = class {
   /**
    * @param {number} width
    * @param {number} height
@@ -350,49 +349,49 @@
 };
 
 /**
- * @param {?Size} size
+ * @param {?UI.Size} size
  * @return {boolean}
  */
-Size.prototype.isEqual = function(size) {
+UI.Size.prototype.isEqual = function(size) {
   return !!size && this.width === size.width && this.height === size.height;
 };
 
 /**
- * @param {!Size|number} size
- * @return {!Size}
+ * @param {!UI.Size|number} size
+ * @return {!UI.Size}
  */
-Size.prototype.widthToMax = function(size) {
-  return new Size(Math.max(this.width, (typeof size === 'number' ? size : size.width)), this.height);
+UI.Size.prototype.widthToMax = function(size) {
+  return new UI.Size(Math.max(this.width, (typeof size === 'number' ? size : size.width)), this.height);
 };
 
 /**
- * @param {!Size|number} size
- * @return {!Size}
+ * @param {!UI.Size|number} size
+ * @return {!UI.Size}
  */
-Size.prototype.addWidth = function(size) {
-  return new Size(this.width + (typeof size === 'number' ? size : size.width), this.height);
+UI.Size.prototype.addWidth = function(size) {
+  return new UI.Size(this.width + (typeof size === 'number' ? size : size.width), this.height);
 };
 
 /**
- * @param {!Size|number} size
- * @return {!Size}
+ * @param {!UI.Size|number} size
+ * @return {!UI.Size}
  */
-Size.prototype.heightToMax = function(size) {
-  return new Size(this.width, Math.max(this.height, (typeof size === 'number' ? size : size.height)));
+UI.Size.prototype.heightToMax = function(size) {
+  return new UI.Size(this.width, Math.max(this.height, (typeof size === 'number' ? size : size.height)));
 };
 
 /**
- * @param {!Size|number} size
- * @return {!Size}
+ * @param {!UI.Size|number} size
+ * @return {!UI.Size}
  */
-Size.prototype.addHeight = function(size) {
-  return new Size(this.width, this.height + (typeof size === 'number' ? size : size.height));
+UI.Size.prototype.addHeight = function(size) {
+  return new UI.Size(this.width, this.height + (typeof size === 'number' ? size : size.height));
 };
 
 /**
  * @unrestricted
  */
-var Insets = class {
+UI.Insets = class {
   /**
    * @param {number} left
    * @param {number} top
@@ -407,7 +406,7 @@
   }
 
   /**
-   * @param {?Insets} insets
+   * @param {?UI.Insets} insets
    * @return {boolean}
    */
   isEqual(insets) {
@@ -419,7 +418,7 @@
 /**
  * @unrestricted
  */
-Common.Rect = class {
+UI.Rect = class {
   /**
    * @param {number} left
    * @param {number} top
@@ -434,7 +433,7 @@
   }
 
   /**
-   * @param {?Common.Rect} rect
+   * @param {?UI.Rect} rect
    * @return {boolean}
    */
   isEqual(rect) {
@@ -444,36 +443,36 @@
 
   /**
    * @param {number} scale
-   * @return {!Common.Rect}
+   * @return {!UI.Rect}
    */
   scale(scale) {
-    return new Common.Rect(this.left * scale, this.top * scale, this.width * scale, this.height * scale);
+    return new UI.Rect(this.left * scale, this.top * scale, this.width * scale, this.height * scale);
   }
 
   /**
-   * @return {!Size}
+   * @return {!UI.Size}
    */
   size() {
-    return new Size(this.width, this.height);
+    return new UI.Size(this.width, this.height);
   }
 };
 
 /**
  * @unrestricted
  */
-var Constraints = class {
+UI.Constraints = class {
   /**
-   * @param {!Size=} minimum
-   * @param {?Size=} preferred
+   * @param {!UI.Size=} minimum
+   * @param {?UI.Size=} preferred
    */
   constructor(minimum, preferred) {
     /**
-     * @type {!Size}
+     * @type {!UI.Size}
      */
-    this.minimum = minimum || new Size(0, 0);
+    this.minimum = minimum || new UI.Size(0, 0);
 
     /**
-     * @type {!Size}
+     * @type {!UI.Size}
      */
     this.preferred = preferred || this.minimum;
 
@@ -483,49 +482,49 @@
 };
 
 /**
- * @param {?Constraints} constraints
+ * @param {?UI.Constraints} constraints
  * @return {boolean}
  */
-Constraints.prototype.isEqual = function(constraints) {
+UI.Constraints.prototype.isEqual = function(constraints) {
   return !!constraints && this.minimum.isEqual(constraints.minimum) && this.preferred.isEqual(constraints.preferred);
 };
 
 /**
- * @param {!Constraints|number} value
- * @return {!Constraints}
+ * @param {!UI.Constraints|number} value
+ * @return {!UI.Constraints}
  */
-Constraints.prototype.widthToMax = function(value) {
+UI.Constraints.prototype.widthToMax = function(value) {
   if (typeof value === 'number')
-    return new Constraints(this.minimum.widthToMax(value), this.preferred.widthToMax(value));
-  return new Constraints(this.minimum.widthToMax(value.minimum), this.preferred.widthToMax(value.preferred));
+    return new UI.Constraints(this.minimum.widthToMax(value), this.preferred.widthToMax(value));
+  return new UI.Constraints(this.minimum.widthToMax(value.minimum), this.preferred.widthToMax(value.preferred));
 };
 
 /**
- * @param {!Constraints|number} value
- * @return {!Constraints}
+ * @param {!UI.Constraints|number} value
+ * @return {!UI.Constraints}
  */
-Constraints.prototype.addWidth = function(value) {
+UI.Constraints.prototype.addWidth = function(value) {
   if (typeof value === 'number')
-    return new Constraints(this.minimum.addWidth(value), this.preferred.addWidth(value));
-  return new Constraints(this.minimum.addWidth(value.minimum), this.preferred.addWidth(value.preferred));
+    return new UI.Constraints(this.minimum.addWidth(value), this.preferred.addWidth(value));
+  return new UI.Constraints(this.minimum.addWidth(value.minimum), this.preferred.addWidth(value.preferred));
 };
 
 /**
- * @param {!Constraints|number} value
- * @return {!Constraints}
+ * @param {!UI.Constraints|number} value
+ * @return {!UI.Constraints}
  */
-Constraints.prototype.heightToMax = function(value) {
+UI.Constraints.prototype.heightToMax = function(value) {
   if (typeof value === 'number')
-    return new Constraints(this.minimum.heightToMax(value), this.preferred.heightToMax(value));
-  return new Constraints(this.minimum.heightToMax(value.minimum), this.preferred.heightToMax(value.preferred));
+    return new UI.Constraints(this.minimum.heightToMax(value), this.preferred.heightToMax(value));
+  return new UI.Constraints(this.minimum.heightToMax(value.minimum), this.preferred.heightToMax(value.preferred));
 };
 
 /**
- * @param {!Constraints|number} value
- * @return {!Constraints}
+ * @param {!UI.Constraints|number} value
+ * @return {!UI.Constraints}
  */
-Constraints.prototype.addHeight = function(value) {
+UI.Constraints.prototype.addHeight = function(value) {
   if (typeof value === 'number')
-    return new Constraints(this.minimum.addHeight(value), this.preferred.addHeight(value));
-  return new Constraints(this.minimum.addHeight(value.minimum), this.preferred.addHeight(value.preferred));
+    return new UI.Constraints(this.minimum.addHeight(value), this.preferred.addHeight(value));
+  return new UI.Constraints(this.minimum.addHeight(value.minimum), this.preferred.addHeight(value.preferred));
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js b/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
index bee15f6..ee90636 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
@@ -603,7 +603,7 @@
     var totalSize = this._totalSizeDIP();
     var zoomFactor = this._constraintsInDip ? 1 : UI.zoomManager.zoomFactor();
 
-    var constraints = this._sidebarWidget ? this._sidebarWidget.constraints() : new Constraints();
+    var constraints = this._sidebarWidget ? this._sidebarWidget.constraints() : new UI.Constraints();
     var minSidebarSize = this.isVertical() ? constraints.minimum.width : constraints.minimum.height;
     if (!minSidebarSize)
       minSidebarSize = UI.SplitWidget.MinPadding;
@@ -620,7 +620,7 @@
       preferredSidebarSize = Math.max(sidebarSize, minSidebarSize);
     preferredSidebarSize += zoomFactor;  // 1 css pixel for splitter border.
 
-    constraints = this._mainWidget ? this._mainWidget.constraints() : new Constraints();
+    constraints = this._mainWidget ? this._mainWidget.constraints() : new UI.Constraints();
     var minMainSize = this.isVertical() ? constraints.minimum.width : constraints.minimum.height;
     if (!minMainSize)
       minMainSize = UI.SplitWidget.MinPadding;
@@ -684,16 +684,16 @@
 
   /**
    * @override
-   * @return {!Constraints}
+   * @return {!UI.Constraints}
    */
   calculateConstraints() {
     if (this._showMode === UI.SplitWidget.ShowMode.OnlyMain)
-      return this._mainWidget ? this._mainWidget.constraints() : new Constraints();
+      return this._mainWidget ? this._mainWidget.constraints() : new UI.Constraints();
     if (this._showMode === UI.SplitWidget.ShowMode.OnlySidebar)
-      return this._sidebarWidget ? this._sidebarWidget.constraints() : new Constraints();
+      return this._sidebarWidget ? this._sidebarWidget.constraints() : new UI.Constraints();
 
-    var mainConstraints = this._mainWidget ? this._mainWidget.constraints() : new Constraints();
-    var sidebarConstraints = this._sidebarWidget ? this._sidebarWidget.constraints() : new Constraints();
+    var mainConstraints = this._mainWidget ? this._mainWidget.constraints() : new UI.Constraints();
+    var sidebarConstraints = this._sidebarWidget ? this._sidebarWidget.constraints() : new UI.Constraints();
     var min = UI.SplitWidget.MinPadding;
     if (this._isVertical) {
       mainConstraints = mainConstraints.widthToMax(min).addWidth(1);  // 1 for splitter
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js b/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js
index 64313e21..5cc3500 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js
@@ -453,16 +453,16 @@
 
   /**
    * @override
-   * @return {!Constraints}
+   * @return {!UI.Constraints}
    */
   calculateConstraints() {
     var constraints = super.calculateConstraints();
-    var minContentConstraints = new Constraints(new Size(0, 0), new Size(50, 50));
+    var minContentConstraints = new UI.Constraints(new UI.Size(0, 0), new UI.Size(50, 50));
     constraints = constraints.widthToMax(minContentConstraints).heightToMax(minContentConstraints);
     if (this._verticalTabLayout)
-      constraints = constraints.addWidth(new Constraints(new Size(120, 0)));
+      constraints = constraints.addWidth(new UI.Constraints(new UI.Size(120, 0)));
     else
-      constraints = constraints.addHeight(new Constraints(new Size(0, 30)));
+      constraints = constraints.addHeight(new UI.Constraints(new UI.Size(0, 30)));
     return constraints;
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
index e7beb227..ef8aed63 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
@@ -990,7 +990,7 @@
 /**
  * @param {!Element} element
  * @param {?Element=} containerElement
- * @return {!Size}
+ * @return {!UI.Size}
  */
 UI.measurePreferredSize = function(element, containerElement) {
   var oldParent = element.parentElement;
@@ -1005,7 +1005,7 @@
     oldParent.insertBefore(element, oldNextSibling);
   else
     element.remove();
-  return new Size(result.width, result.height);
+  return new UI.Size(result.width, result.height);
 };
 
 /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/Widget.js b/third_party/WebKit/Source/devtools/front_end/ui/Widget.js
index e92543a..c030963 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/Widget.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/Widget.js
@@ -502,7 +502,7 @@
   }
 
   /**
-   * @return {!Size}
+   * @return {!UI.Size}
    */
   measurePreferredSize() {
     var document = this.element.ownerDocument;
@@ -511,7 +511,7 @@
 
     UI.Widget._originalAppendChild.call(document.body, this.element);
     this.element.positionAt(0, 0);
-    var result = new Size(this.element.offsetWidth, this.element.offsetHeight);
+    var result = new UI.Size(this.element.offsetWidth, this.element.offsetHeight);
 
     this.element.positionAt(undefined, undefined);
     if (oldParent)
@@ -522,14 +522,14 @@
   }
 
   /**
-   * @return {!Constraints}
+   * @return {!UI.Constraints}
    */
   calculateConstraints() {
-    return new Constraints();
+    return new UI.Constraints();
   }
 
   /**
-   * @return {!Constraints}
+   * @return {!UI.Constraints}
    */
   constraints() {
     if (typeof this._constraints !== 'undefined')
@@ -546,7 +546,7 @@
    * @param {number} preferredHeight
    */
   setMinimumAndPreferredSizes(width, height, preferredWidth, preferredHeight) {
-    this._constraints = new Constraints(new Size(width, height), new Size(preferredWidth, preferredHeight));
+    this._constraints = new UI.Constraints(new UI.Size(width, height), new UI.Size(preferredWidth, preferredHeight));
     this.invalidateConstraints();
   }
 
@@ -555,7 +555,7 @@
    * @param {number} height
    */
   setMinimumSize(width, height) {
-    this._constraints = new Constraints(new Size(width, height));
+    this._constraints = new UI.Constraints(new UI.Size(width, height));
     this.invalidateConstraints();
   }
 
@@ -615,10 +615,10 @@
 
   /**
    * @override
-   * @return {!Constraints}
+   * @return {!UI.Constraints}
    */
   calculateConstraints() {
-    var constraints = new Constraints();
+    var constraints = new UI.Constraints();
 
     /**
      * @this {!UI.Widget}
@@ -649,10 +649,10 @@
 
   /**
    * @override
-   * @return {!Constraints}
+   * @return {!UI.Constraints}
    */
   calculateConstraints() {
-    var constraints = new Constraints();
+    var constraints = new UI.Constraints();
 
     /**
      * @this {!UI.Widget}
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/module.json b/third_party/WebKit/Source/devtools/front_end/ui/module.json
index 5cae606..83097b2 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/ui/module.json
@@ -48,7 +48,8 @@
         "TabbedPane.js",
         "UIUtils.js",
         "ZoomManager.js",
-        "ShortcutsScreen.js"
+        "ShortcutsScreen.js",
+        "Geometry.js"
     ],
     "resources": [
         "checkboxTextLabel.css",
diff --git a/third_party/WebKit/Source/devtools/scripts/extract_module/extract_module.js b/third_party/WebKit/Source/devtools/scripts/extract_module/extract_module.js
index 1928a22..76934f8 100644
--- a/third_party/WebKit/Source/devtools/scripts/extract_module/extract_module.js
+++ b/third_party/WebKit/Source/devtools/scripts/extract_module/extract_module.js
@@ -24,17 +24,18 @@
 const MODULES_TO_REMOVE = [];
 
 const JS_FILES_MAPPING = [
-  {file: 'profiler/HeapSnapshotModel.js', new: 'heap_snapshot_model'},
+  {file: 'common/CSSShadowModel.js', existing: 'inline_editor'},
+  {file: 'common/Geometry.js', existing: 'ui'},
   // {file: 'module/file.js', existing: 'module'}
 ];
 
 const MODULE_MAPPING = {
-  heap_snapshot_model: {
-    dependencies: [],
-    dependents: ['heap_snapshot_worker', 'profiler'],
-    applications: ['inspector.json'], // need to manually add to heap snapshot worker b/c it's autostart
-    autostart: false,
-  },
+  // heap_snapshot_model: {
+  //   dependencies: [],
+  //   dependents: ['heap_snapshot_worker', 'profiler'],
+  //   applications: ['inspector.json'], // need to manually add to heap snapshot worker b/c it's autostart
+  //   autostart: false,
+  // },
 };
 
 const NEW_DEPENDENCIES_BY_EXISTING_MODULES = {
@@ -166,10 +167,16 @@
       let name = match[1];
 
       var currentModule = fileObj.file.split('/')[0];
-      if (name.split('.')[0] !== mapModuleToNamespace(currentModule))
+      if (name.split('.')[0] !== mapModuleToNamespace(currentModule)) {
         console.log(`POSSIBLE ISSUE: identifier: ${name} found in ${currentModule}`);
-      else
+        // one-off
+        if (name.includes('UI.')) {
+          console.log(`including ${name} anyways`);
+          identifiers.push(name)
+        }
+      } else {
         identifiers.push(name);
+      }
     }
     return identifiers;
   }
@@ -263,6 +270,8 @@
   }
 
   function addContentToLinesInSortedOrder({content, startLine, endLine, linesToInsert}) {
+    if (linesToInsert.length === 0)
+      return content;
     let lines = content.split('\n');
     let seenStartLine = false;
     let contentStack = linesToInsert.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).reverse();
@@ -302,14 +311,6 @@
       let components = identifier.split('.');
       components[0] = mapModuleToNamespace(targetModule);
       let newIdentifier = components.join('.');
-      // one-off
-      if (targetModule === 'heap_snapshot_model' && components[1] === 'HeapSnapshotCommon') {
-        newIdentifier = [components[0]].concat(components.slice(2)).join('.');
-        if (newIdentifier === 'HeapSnapshotModel') {
-          identifier = 'Profiler.HeapSnapshotCommon = {};\n\n';
-          newIdentifier = '';
-        }
-      }
       map.set(identifier, newIdentifier);
     }
   }
diff --git a/third_party/WebKit/Source/devtools/scripts/namespaces.js b/third_party/WebKit/Source/devtools/scripts/namespaces.js
index e395f1c6..ded82ef 100644
--- a/third_party/WebKit/Source/devtools/scripts/namespaces.js
+++ b/third_party/WebKit/Source/devtools/scripts/namespaces.js
@@ -1,5 +1,7 @@
 const fs = require('fs');
 
+const TARGET_MODULE = 'UI';
+
 function depends(module, from)
 {
     if (module === from)
@@ -58,7 +60,7 @@
 
         var newName;
 
-        newName = moduleName + "." + name;
+        newName = TARGET_MODULE + "." + name;
         var existing = map.get(name);
         if (existing && existing.weight > weight)
             continue;
@@ -75,18 +77,22 @@
     for (var key of sortedKeys) {
         var originalIdentifier = key;
         var newIdentifier = map.get(key).name;
-        newContent = newContent.split("\n").map(function (line) {
-            return processLine(line);
-        }).join("\n");
+        newContent = newContent.split("\n").map(line => processLine(line, originalIdentifier, newIdentifier)).join("\n");
     }
 
     if (content !== newContent)
         fs.writeFileSync(filePath, newContent);
 }
 
-function processLine(line) {
-    // Add transformation logic
-    return line;
+function processLine(line, originalIdentifier, newIdentifier) {
+    return line.replace(new RegExp(`^var ${originalIdentifier}`, "g"), `${newIdentifier}`)
+      .replace(new RegExp(`^function ${originalIdentifier}`, "g"), `${newIdentifier} = function`)
+      .replace(new RegExp(`^${originalIdentifier}\\.`, "g"), `${newIdentifier}.`)
+      .replace(new RegExp(`([^."'])(\\b${originalIdentifier}\\b)(?!(\.js|[ ]|[']))`, "g"), usageReplacer);
+
+    function usageReplacer(match, p1) {
+        return [p1, newIdentifier].join("");
+    }
 }
 
 function walkSync(currentDirPath, process, json) {
@@ -114,7 +120,7 @@
 
 sortedKeys = Array.from(map.keys());
 sortedKeys.sort((a, b) => a.localeCompare(b));
-
+sortedKeys = ['Size', 'Insets', 'Constraints'];
 for (var key of sortedKeys)
     console.log(key + " => " + map.get(key).name);
 
diff --git a/third_party/WebKit/Source/modules/csspaint/WindowPaintWorklet.cpp b/third_party/WebKit/Source/modules/csspaint/WindowPaintWorklet.cpp
index d3dbc99..63d4a4a 100644
--- a/third_party/WebKit/Source/modules/csspaint/WindowPaintWorklet.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/WindowPaintWorklet.cpp
@@ -11,7 +11,7 @@
 namespace blink {
 
 WindowPaintWorklet::WindowPaintWorklet(LocalDOMWindow& window)
-    : DOMWindowProperty(window.frame()) {}
+    : Supplement<LocalDOMWindow>(window) {}
 
 const char* WindowPaintWorklet::supplementName() {
   return "WindowPaintWorklet";
@@ -34,15 +34,14 @@
 }
 
 PaintWorklet* WindowPaintWorklet::paintWorklet() {
-  if (!m_paintWorklet && frame())
-    m_paintWorklet = PaintWorklet::create(frame());
+  if (!m_paintWorklet && host()->frame())
+    m_paintWorklet = PaintWorklet::create(host()->frame());
   return m_paintWorklet.get();
 }
 
 DEFINE_TRACE(WindowPaintWorklet) {
   visitor->trace(m_paintWorklet);
   Supplement<LocalDOMWindow>::trace(visitor);
-  DOMWindowProperty::trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/csspaint/WindowPaintWorklet.h b/third_party/WebKit/Source/modules/csspaint/WindowPaintWorklet.h
index 8689695..1668c8e 100644
--- a/third_party/WebKit/Source/modules/csspaint/WindowPaintWorklet.h
+++ b/third_party/WebKit/Source/modules/csspaint/WindowPaintWorklet.h
@@ -5,7 +5,6 @@
 #ifndef WindowPaintWorklet_h
 #define WindowPaintWorklet_h
 
-#include "core/frame/DOMWindowProperty.h"
 #include "core/frame/LocalDOMWindow.h"
 #include "modules/ModulesExport.h"
 #include "platform/Supplementable.h"
@@ -20,8 +19,7 @@
 
 class MODULES_EXPORT WindowPaintWorklet final
     : public GarbageCollected<WindowPaintWorklet>,
-      public Supplement<LocalDOMWindow>,
-      public DOMWindowProperty {
+      public Supplement<LocalDOMWindow> {
   USING_GARBAGE_COLLECTED_MIXIN(WindowPaintWorklet);
 
  public:
diff --git a/third_party/WebKit/Source/modules/eventsource/EventSource.cpp b/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
index 07900d7..33034f98 100644
--- a/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
+++ b/third_party/WebKit/Source/modules/eventsource/EventSource.cpp
@@ -173,6 +173,8 @@
   resourceLoaderOptions.securityOrigin = origin;
 
   InspectorInstrumentation::willSendEventSourceRequest(&executionContext, this);
+  // TODO(yhirano): Remove this CHECK once https://crbug.com/667254 is fixed.
+  CHECK(!m_loader);
   // InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient
   // will be called synchronously.
   m_loader = ThreadableLoader::create(executionContext, this, options,
diff --git a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
index 900b1e9..833e2c6 100644
--- a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
+++ b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
@@ -838,6 +838,8 @@
       break;
   }
   InspectorInstrumentation::willStartFetch(m_executionContext, this);
+  // TODO(yhirano): Remove this CHECK once https://crbug.com/667254 is fixed.
+  CHECK(!m_loader);
   m_loader =
       ThreadableLoader::create(*m_executionContext, this,
                                threadableLoaderOptions, resourceLoaderOptions);
diff --git a/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.cpp b/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.cpp
index 00ba58c..9cec819 100644
--- a/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.cpp
+++ b/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.cpp
@@ -120,6 +120,8 @@
   resourceRequest.setPriority(ResourceLoadPriorityMedium);
   resourceRequest.setRequestorOrigin(executionContext->getSecurityOrigin());
 
+  // TODO(yhirano): Remove this CHECK once https://crbug.com/667254 is fixed.
+  CHECK(!m_threadableLoader);
   m_threadableLoader = ThreadableLoader::create(
       *executionContext, this, threadableLoaderOptions, resourceLoaderOptions);
   m_threadableLoader->start(resourceRequest);
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
index 90bcff3..d932ef3 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -338,32 +338,9 @@
 
   m_previousInterestRect = *interestRect;
   m_client->paintContents(this, context, m_paintingPhase, *interestRect);
-  notifyFirstPaintToClient();
   return true;
 }
 
-void GraphicsLayer::notifyFirstPaintToClient() {
-  bool isFirstPaint = false;
-  if (!m_painted) {
-    DisplayItemList& itemList = m_paintController->newDisplayItemList();
-    for (DisplayItem& item : itemList) {
-      DisplayItem::Type type = item.getType();
-      if (type == DisplayItem::kDocumentBackground &&
-          !m_paintController->nonDefaultBackgroundColorPainted()) {
-        continue;
-      }
-      if (DisplayItem::isDrawingType(type) &&
-          static_cast<const DrawingDisplayItem&>(item).picture()) {
-        m_painted = true;
-        isFirstPaint = true;
-        break;
-      }
-    }
-  }
-  m_client->notifyPaint(isFirstPaint, m_paintController->textPainted(),
-                        m_paintController->imagePainted());
-}
-
 void GraphicsLayer::updateChildList() {
   WebLayer* childHost = m_layer->layer();
   childHost->removeAllChildren();
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
index 0fc99f5..21a25d0 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -314,8 +314,6 @@
 
   void incrementPaintCount() { ++m_paintCount; }
 
-  void notifyFirstPaintToClient();
-
   // Helper functions used by settors to keep layer's the state consistent.
   void updateChildList();
   void updateLayerIsDrawable();
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
index c121f147..1a9f4ae 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
@@ -72,9 +72,6 @@
   virtual ~GraphicsLayerClient() {}
 
   virtual void invalidateTargetElementForTesting() {}
-  virtual void notifyPaint(bool isFirstPaint,
-                           bool textPainted,
-                           bool imagePainted) {}
 
   virtual IntRect computeInterestRect(
       const GraphicsLayer*,
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
index 4f0fc55..d016713 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -527,6 +527,21 @@
     }
   }
 
+  if (!m_firstPainted) {
+    for (const auto& item : m_newDisplayItemList) {
+      if (item.isDrawing() &&
+          // Here we ignore all document-background paintings because we don't
+          // know if the background is default. ViewPainter should have called
+          // setFirstPainted() if this display item is for non-default
+          // background.
+          item.getType() != DisplayItem::kDocumentBackground &&
+          item.drawsContent()) {
+        m_firstPainted = true;
+        break;
+      }
+    }
+  }
+
   for (auto* client : skippedCacheClients)
     client->setDisplayItemsUncached();
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
index b7aecc0..7d5c514 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
@@ -160,18 +160,13 @@
     m_subsequenceCachingDisabled = disable;
   }
 
+  bool firstPainted() const { return m_firstPainted; }
+  void setFirstPainted() { m_firstPainted = true; }
   bool textPainted() const { return m_textPainted; }
   void setTextPainted() { m_textPainted = true; }
   bool imagePainted() const { return m_imagePainted; }
   void setImagePainted() { m_imagePainted = true; }
 
-  bool nonDefaultBackgroundColorPainted() const {
-    return m_nonDefaultBackgroundColorPainted;
-  }
-  void setNonDefaultBackgroundColorPainted() {
-    m_nonDefaultBackgroundColorPainted = true;
-  }
-
   // Returns displayItemList added using createAndAppend() since beginning or
   // the last commitNewDisplayItems(). Use with care.
   DisplayItemList& newDisplayItemList() { return m_newDisplayItemList; }
@@ -204,9 +199,9 @@
       : m_newDisplayItemList(0),
         m_constructionDisabled(false),
         m_subsequenceCachingDisabled(false),
+        m_firstPainted(false),
         m_textPainted(false),
         m_imagePainted(false),
-        m_nonDefaultBackgroundColorPainted(false),
         m_skippingCacheCount(0),
         m_numCachedNewItems(0),
         m_currentCachedSubsequenceBeginIndexInNewList(kNotFound)
@@ -306,11 +301,13 @@
   // caching.
   bool m_subsequenceCachingDisabled;
 
-  // Indicates this PaintController has ever had text. It is never reset to
-  // false.
+  // The following fields indicate that this PaintController has ever had
+  // first-paint, text or image painted. They are never reset to false.
+  // First-paint is defined in https://github.com/WICG/paint-timing. It excludes
+  // default background paint.
+  bool m_firstPainted;
   bool m_textPainted;
   bool m_imagePainted;
-  bool m_nonDefaultBackgroundColorPainted;
 
   int m_skippingCacheCount;
 
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.h b/third_party/WebKit/Source/platform/heap/HeapPage.h
index 69d369d..8fbc94a 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.h
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.h
@@ -925,6 +925,9 @@
 }
 
 NO_SANITIZE_ADDRESS inline void HeapObjectHeader::markDead() {
+  // A Dead state should not happen in a per-thread heap world.
+  // TODO(haraken): Remove code to handle the Dead state.
+  CHECK(false);
   ASSERT(checkHeader());
   ASSERT(!isMarked());
   m_encoded |= headerDeadBitMask;
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp b/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp
index 688c0b3..4909395 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp
@@ -32,12 +32,11 @@
 
 }  // namespace
 
-class ScrollableAreaTest : public ScrollbarTestSuite {};
+using ScrollableAreaTest = testing::Test;
 
 TEST_F(ScrollableAreaTest, ScrollAnimatorCurrentPositionShouldBeSync) {
-  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler,
-                               const TestingPlatformSupport::Config&>
-      platform(m_config);
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
 
   MockScrollableArea* scrollableArea =
       MockScrollableArea::create(ScrollOffset(0, 100));
@@ -46,9 +45,8 @@
 }
 
 TEST_F(ScrollableAreaTest, ScrollbarTrackAndThumbRepaint) {
-  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler,
-                               const TestingPlatformSupport::Config&>
-      platform(m_config);
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
 
   ScrollbarThemeWithMockInvalidation theme;
   MockScrollableArea* scrollableArea =
@@ -89,9 +87,8 @@
 }
 
 TEST_F(ScrollableAreaTest, ScrollbarGraphicsLayerInvalidation) {
-  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler,
-                               const TestingPlatformSupport::Config&>
-      platform(m_config);
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
 
   ScrollbarTheme::setMockScrollbarsEnabled(true);
   MockScrollableArea* scrollableArea =
@@ -116,9 +113,8 @@
 }
 
 TEST_F(ScrollableAreaTest, InvalidatesNonCompositedScrollbarsWhenThumbMoves) {
-  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler,
-                               const TestingPlatformSupport::Config&>
-      platform(m_config);
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
 
   ScrollbarThemeWithMockInvalidation theme;
   MockScrollableArea* scrollableArea =
@@ -160,9 +156,8 @@
 }
 
 TEST_F(ScrollableAreaTest, InvalidatesCompositedScrollbarsIfPartsNeedRepaint) {
-  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler,
-                               const TestingPlatformSupport::Config&>
-      platform(m_config);
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
 
   ScrollbarThemeWithMockInvalidation theme;
   MockScrollableArea* scrollableArea =
@@ -242,9 +237,8 @@
 }
 
 TEST_F(ScrollableAreaTest, RecalculatesScrollbarOverlayIfBackgroundChanges) {
-  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler,
-                               const TestingPlatformSupport::Config&>
-      platform(m_config);
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
 
   MockScrollableArea* scrollableArea =
       MockScrollableArea::create(ScrollOffset(0, 100));
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarTestSuite.h b/third_party/WebKit/Source/platform/scroll/ScrollbarTestSuite.h
index 6e99ad8f9..cd0402a 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarTestSuite.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarTestSuite.h
@@ -9,7 +9,6 @@
 #include "platform/scroll/ScrollableArea.h"
 #include "platform/scroll/Scrollbar.h"
 #include "platform/scroll/ScrollbarThemeMock.h"
-#include "platform/testing/TestingPlatformSupport.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "wtf/PtrUtil.h"
 #include <memory>
@@ -82,18 +81,6 @@
   ScrollOffset m_maximumScrollOffset;
 };
 
-class ScrollbarTestSuite : public testing::Test {
- public:
-  ScrollbarTestSuite() {}
-
-  void SetUp() override {
-    m_config.compositorSupport = Platform::current()->compositorSupport();
-  }
-
- protected:
-  TestingPlatformSupport::Config m_config;
-};
-
 }  // namespace blink
 
 #endif
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeAuraTest.cpp b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeAuraTest.cpp
index d4601f19..b8d58e3 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeAuraTest.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeAuraTest.cpp
@@ -5,6 +5,7 @@
 #include "platform/scroll/ScrollbarThemeAura.h"
 
 #include "platform/scroll/ScrollbarTestSuite.h"
+#include "platform/testing/TestingPlatformSupport.h"
 
 namespace blink {
 
@@ -28,12 +29,11 @@
 
 }  // namespace
 
-class ScrollbarThemeAuraTest : public ScrollbarTestSuite {};
+using ScrollbarThemeAuraTest = testing::Test;
 
 TEST_F(ScrollbarThemeAuraTest, ButtonSizeHorizontal) {
-  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler,
-                               const TestingPlatformSupport::Config&>
-      platform(m_config);
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
 
   MockScrollableArea* mockScrollableArea = MockScrollableArea::create();
   ScrollbarThemeMock mockTheme;
@@ -57,9 +57,8 @@
 }
 
 TEST_F(ScrollbarThemeAuraTest, ButtonSizeVertical) {
-  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler,
-                               const TestingPlatformSupport::Config&>
-      platform(m_config);
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
 
   MockScrollableArea* mockScrollableArea = MockScrollableArea::create();
   ScrollbarThemeMock mockTheme;
@@ -83,9 +82,8 @@
 }
 
 TEST_F(ScrollbarThemeAuraTest, NoButtonsReturnsSize0) {
-  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler,
-                               const TestingPlatformSupport::Config&>
-      platform(m_config);
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
 
   MockScrollableArea* mockScrollableArea = MockScrollableArea::create();
   ScrollbarThemeMock mockTheme;
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlayTest.cpp b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlayTest.cpp
index db7f427..1a0fec8 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlayTest.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarThemeOverlayTest.cpp
@@ -5,18 +5,18 @@
 #include "platform/scroll/ScrollbarThemeOverlay.h"
 
 #include "platform/scroll/ScrollbarTestSuite.h"
+#include "platform/testing/TestingPlatformSupport.h"
 
 namespace blink {
 
 using testing::NiceMock;
 using testing::Return;
 
-class ScrollbarThemeOverlayTest : public ScrollbarTestSuite {};
+using ScrollbarThemeOverlayTest = testing::Test;
 
 TEST_F(ScrollbarThemeOverlayTest, PaintInvalidation) {
-  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler,
-                               const TestingPlatformSupport::Config&>
-      platform(m_config);
+  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+      platform;
 
   NiceMock<MockScrollableArea>* mockScrollableArea =
       new NiceMock<MockScrollableArea>(ScrollOffset(100, 100));
diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
index 850d236..5ed2efe 100644
--- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
+++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
@@ -190,11 +190,9 @@
 
 void FrameLoaderClientImpl::didCreateScriptContext(
     v8::Local<v8::Context> context,
-    int extensionGroup,
     int worldId) {
   if (m_webFrame->client())
-    m_webFrame->client()->didCreateScriptContext(m_webFrame, context,
-                                                 extensionGroup, worldId);
+    m_webFrame->client()->didCreateScriptContext(m_webFrame, context, worldId);
 }
 
 void FrameLoaderClientImpl::willReleaseScriptContext(
@@ -205,13 +203,7 @@
                                                    worldId);
 }
 
-bool FrameLoaderClientImpl::allowScriptExtension(const String& extensionName,
-                                                 int extensionGroup,
-                                                 int worldId) {
-  if (m_webFrame->contentSettingsClient())
-    return m_webFrame->contentSettingsClient()->allowScriptExtension(
-        extensionName, extensionGroup, worldId);
-
+bool FrameLoaderClientImpl::allowScriptExtensions() {
   return true;
 }
 
diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h
index 2fc1deb..646ffc0 100644
--- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h
+++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h
@@ -66,15 +66,11 @@
   void runScriptsAtDocumentReady(bool documentIsEmpty) override;
 
   void didCreateScriptContext(v8::Local<v8::Context>,
-                              int extensionGroup,
                               int worldId) override;
   void willReleaseScriptContext(v8::Local<v8::Context>, int worldId) override;
 
-  // Returns true if we should allow the given V8 extension to be added to
-  // the script context at the currently loading page and given extension group.
-  bool allowScriptExtension(const String& extensionName,
-                            int extensionGroup,
-                            int worldId) override;
+  // Returns true if we should allow register V8 extensions to be added.
+  bool allowScriptExtensions() override;
 
   bool hasWebView() const override;
   bool inShadowTree() const override;
diff --git a/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp b/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp
index d3e6692..1f41b5e 100644
--- a/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp
+++ b/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp
@@ -26,7 +26,6 @@
  public:
   WebScriptExecutor(const HeapVector<ScriptSourceCode>& sources,
                     int worldID,
-                    int extensionGroup,
                     bool userGesture);
 
   Vector<v8::Local<v8::Value>> execute(LocalFrame*) override;
@@ -39,18 +38,15 @@
  private:
   HeapVector<ScriptSourceCode> m_sources;
   int m_worldID;
-  int m_extensionGroup;
   bool m_userGesture;
 };
 
 WebScriptExecutor::WebScriptExecutor(
     const HeapVector<ScriptSourceCode>& sources,
     int worldID,
-    int extensionGroup,
     bool userGesture)
     : m_sources(sources),
       m_worldID(worldID),
-      m_extensionGroup(extensionGroup),
       m_userGesture(userGesture) {}
 
 Vector<v8::Local<v8::Value>> WebScriptExecutor::execute(LocalFrame* frame) {
@@ -64,7 +60,7 @@
   Vector<v8::Local<v8::Value>> results;
   if (m_worldID) {
     frame->script().executeScriptInIsolatedWorld(m_worldID, m_sources,
-                                                 m_extensionGroup, &results);
+                                                 &results);
   } else {
     v8::Local<v8::Value> scriptValue =
         frame->script().executeScriptInMainWorldAndReturnValue(
@@ -136,17 +132,15 @@
     LocalFrame* frame,
     int worldID,
     const HeapVector<ScriptSourceCode>& sources,
-    int extensionGroup,
     bool userGesture,
     WebScriptExecutionCallback* callback) {
   // TODO(devlin): Passing in a v8::Isolate* directly would be better than
   // toIsolate() here.
   ScriptState* scriptState = ScriptState::forWorld(
-      frame,
-      *DOMWrapperWorld::fromWorldId(toIsolate(frame), worldID, extensionGroup));
+      frame, *DOMWrapperWorld::fromWorldId(toIsolate(frame), worldID));
   SuspendableScriptExecutor* executor = new SuspendableScriptExecutor(
       frame, scriptState, callback,
-      new WebScriptExecutor(sources, worldID, extensionGroup, userGesture));
+      new WebScriptExecutor(sources, worldID, userGesture));
   executor->run();
 }
 
diff --git a/third_party/WebKit/Source/web/SuspendableScriptExecutor.h b/third_party/WebKit/Source/web/SuspendableScriptExecutor.h
index e1f6121..4fbfe2e 100644
--- a/third_party/WebKit/Source/web/SuspendableScriptExecutor.h
+++ b/third_party/WebKit/Source/web/SuspendableScriptExecutor.h
@@ -27,7 +27,6 @@
   static void createAndRun(LocalFrame*,
                            int worldID,
                            const HeapVector<ScriptSourceCode>& sources,
-                           int extensionGroup,
                            bool userGesture,
                            WebScriptExecutionCallback*);
   static void createAndRun(LocalFrame*,
diff --git a/third_party/WebKit/Source/web/WebAssociatedURLLoaderImpl.cpp b/third_party/WebKit/Source/web/WebAssociatedURLLoaderImpl.cpp
index 74a2490..69a0e41 100644
--- a/third_party/WebKit/Source/web/WebAssociatedURLLoaderImpl.cpp
+++ b/third_party/WebKit/Source/web/WebAssociatedURLLoaderImpl.cpp
@@ -410,6 +410,8 @@
 
     Document* document = toDocument(m_observer->lifecycleContext());
     DCHECK(document);
+    // TODO(yhirano): Remove this CHECK once https://crbug.com/667254 is fixed.
+    CHECK(!m_loader);
     m_loader = DocumentThreadableLoader::create(
         *document, m_clientAdapter.get(), options, resourceLoaderOptions);
     m_loader->start(webcoreRequest);
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
index 1b3d3e7..ebd1431 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -664,8 +664,7 @@
 void WebLocalFrameImpl::executeScriptInIsolatedWorld(
     int worldID,
     const WebScriptSource* sourcesIn,
-    unsigned numSources,
-    int extensionGroup) {
+    unsigned numSources) {
   DCHECK(frame());
   CHECK_GT(worldID, 0);
   CHECK_LT(worldID, EmbedderWorldIdLimit);
@@ -673,8 +672,7 @@
   HeapVector<ScriptSourceCode> sources =
       createSourcesVector(sourcesIn, numSources);
   v8::HandleScope handleScope(toIsolate(frame()));
-  frame()->script().executeScriptInIsolatedWorld(worldID, sources,
-                                                 extensionGroup, 0);
+  frame()->script().executeScriptInIsolatedWorld(worldID, sources, 0);
 }
 
 void WebLocalFrameImpl::setIsolatedWorldSecurityOrigin(
@@ -753,7 +751,7 @@
   DCHECK(frame());
 
   SuspendableScriptExecutor::createAndRun(
-      frame(), 0, createSourcesVector(&source, 1), 0, userGesture, callback);
+      frame(), 0, createSourcesVector(&source, 1), userGesture, callback);
 }
 
 void WebLocalFrameImpl::requestExecuteV8Function(
@@ -773,7 +771,6 @@
     int worldID,
     const WebScriptSource* sourcesIn,
     unsigned numSources,
-    int extensionGroup,
     WebVector<v8::Local<v8::Value>>* results) {
   DCHECK(frame());
   CHECK_GT(worldID, 0);
@@ -784,8 +781,8 @@
 
   if (results) {
     Vector<v8::Local<v8::Value>> scriptResults;
-    frame()->script().executeScriptInIsolatedWorld(
-        worldID, sources, extensionGroup, &scriptResults);
+    frame()->script().executeScriptInIsolatedWorld(worldID, sources,
+                                                   &scriptResults);
     WebVector<v8::Local<v8::Value>> v8Results(scriptResults.size());
     for (unsigned i = 0; i < scriptResults.size(); i++)
       v8Results[i] =
@@ -793,8 +790,7 @@
     results->swap(v8Results);
   } else {
     v8::HandleScope handleScope(toIsolate(frame()));
-    frame()->script().executeScriptInIsolatedWorld(worldID, sources,
-                                                   extensionGroup, 0);
+    frame()->script().executeScriptInIsolatedWorld(worldID, sources, 0);
   }
 }
 
@@ -802,7 +798,6 @@
     int worldID,
     const WebScriptSource* sourcesIn,
     unsigned numSources,
-    int extensionGroup,
     bool userGesture,
     WebScriptExecutionCallback* callback) {
   DCHECK(frame());
@@ -810,8 +805,8 @@
   CHECK_LT(worldID, EmbedderWorldIdLimit);
 
   SuspendableScriptExecutor::createAndRun(
-      frame(), worldID, createSourcesVector(sourcesIn, numSources),
-      extensionGroup, userGesture, callback);
+      frame(), worldID, createSourcesVector(sourcesIn, numSources), userGesture,
+      callback);
 }
 
 // TODO(bashi): Consider returning MaybeLocal.
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
index 2ac01c8..1e48d48f 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -107,8 +107,7 @@
   void executeScript(const WebScriptSource&) override;
   void executeScriptInIsolatedWorld(int worldID,
                                     const WebScriptSource* sources,
-                                    unsigned numSources,
-                                    int extensionGroup) override;
+                                    unsigned numSources) override;
   void setIsolatedWorldSecurityOrigin(int worldID,
                                       const WebSecurityOrigin&) override;
   void setIsolatedWorldContentSecurityPolicy(int worldID,
@@ -132,13 +131,11 @@
       int worldID,
       const WebScriptSource* sourcesIn,
       unsigned numSources,
-      int extensionGroup,
       WebVector<v8::Local<v8::Value>>* results) override;
   void requestExecuteScriptInIsolatedWorld(
       int worldID,
       const WebScriptSource* sourceIn,
       unsigned numSources,
-      int extensionGroup,
       bool userGesture,
       WebScriptExecutionCallback*) override;
   v8::Local<v8::Value> callFunctionEvenIfScriptDisabled(
diff --git a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
index 2b214bdc..ba6c90b 100644
--- a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
@@ -164,8 +164,7 @@
 void WebRemoteFrameImpl::executeScriptInIsolatedWorld(
     int worldID,
     const WebScriptSource* sources,
-    unsigned numSources,
-    int extensionGroup) {
+    unsigned numSources) {
   NOTREACHED();
 }
 
@@ -195,7 +194,6 @@
     int worldID,
     const WebScriptSource* sourcesIn,
     unsigned numSources,
-    int extensionGroup,
     WebVector<v8::Local<v8::Value>>* results) {
   NOTREACHED();
 }
diff --git a/third_party/WebKit/Source/web/WebRemoteFrameImpl.h b/third_party/WebKit/Source/web/WebRemoteFrameImpl.h
index c6a3455..8b2c590 100644
--- a/third_party/WebKit/Source/web/WebRemoteFrameImpl.h
+++ b/third_party/WebKit/Source/web/WebRemoteFrameImpl.h
@@ -56,8 +56,7 @@
   void executeScript(const WebScriptSource&) override;
   void executeScriptInIsolatedWorld(int worldID,
                                     const WebScriptSource* sources,
-                                    unsigned numSources,
-                                    int extensionGroup) override;
+                                    unsigned numSources) override;
   void setIsolatedWorldSecurityOrigin(int worldID,
                                       const WebSecurityOrigin&) override;
   void setIsolatedWorldContentSecurityPolicy(int worldID,
@@ -69,7 +68,6 @@
       int worldID,
       const WebScriptSource* sourcesIn,
       unsigned numSources,
-      int extensionGroup,
       WebVector<v8::Local<v8::Value>>* results) override;
   v8::Local<v8::Value> callFunctionEvenIfScriptDisabled(
       v8::Local<v8::Function>,
diff --git a/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp b/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp
index d25a991b..783b060 100644
--- a/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp
@@ -96,7 +96,7 @@
     sources.push_back(ScriptSourceCode(script));
     Vector<v8::Local<v8::Value>> results;
     m_scriptController->executeScriptInIsolatedWorld(isolatedWorldId, sources,
-                                                     extensionGroup, 0);
+                                                     0);
     pumpPendingRequestsForFrameToLoad(m_webViewHelper.webView()->mainFrame());
   }
 
@@ -108,7 +108,6 @@
 
  private:
   static const int isolatedWorldId = 1;
-  static const int extensionGroup = 0;
 
   WebViewHelper m_webViewHelper;
   Persistent<ScriptController> m_scriptController;
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index c0f834a..6665c81 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -4278,7 +4278,6 @@
  private:
   void didCreateScriptContext(WebLocalFrame* frame,
                               v8::Local<v8::Context> context,
-                              int extensionGroup,
                               int worldId) override {
     createNotifications.push_back(
         WTF::makeUnique<Notification>(frame, context, worldId));
@@ -4399,9 +4398,8 @@
   int isolatedWorldId = 42;
   WebScriptSource scriptSource("hi!");
   int numSources = 1;
-  int extensionGroup = 0;
   webViewHelper.webView()->mainFrame()->executeScriptInIsolatedWorld(
-      isolatedWorldId, &scriptSource, numSources, extensionGroup);
+      isolatedWorldId, &scriptSource, numSources);
 
   // We should now have a new create notification.
   ASSERT_EQ(1u, webFrameClient.createNotifications.size());
@@ -4582,7 +4580,6 @@
  public:
   void didCreateScriptContext(WebLocalFrame* frame,
                               v8::Local<v8::Context> context,
-                              int extensionGroup,
                               int worldId) override {
     frame->executeScript(WebScriptSource("window.history = 'replaced';"));
   }
diff --git a/third_party/WebKit/public/web/WebContentSettingsClient.h b/third_party/WebKit/public/web/WebContentSettingsClient.h
index 933c372..b0ae806f 100644
--- a/third_party/WebKit/public/web/WebContentSettingsClient.h
+++ b/third_party/WebKit/public/web/WebContentSettingsClient.h
@@ -66,22 +66,6 @@
     return enabledPerSettings;
   }
 
-  // Controls whether the given script extension should run in a new script
-  // context in this frame. If extensionGroup is 0, the script context is the
-  // frame's main context. Otherwise, it is a context created by
-  // WebLocalFrame::executeScriptInIsolatedWorld with that same extensionGroup
-  // value.
-  virtual bool allowScriptExtension(const WebString& extensionName,
-                                    int extensionGroup) {
-    return true;
-  }
-
-  virtual bool allowScriptExtension(const WebString& extensionName,
-                                    int extensionGroup,
-                                    int worldId) {
-    return allowScriptExtension(extensionName, extensionGroup);
-  }
-
   // Controls whether HTML5 Web Storage is allowed for this frame.
   // If local is true, then this is for local storage, otherwise it's for
   // session storage.
diff --git a/third_party/WebKit/public/web/WebFrame.h b/third_party/WebKit/public/web/WebFrame.h
index 85f2e23..c12e89f 100644
--- a/third_party/WebKit/public/web/WebFrame.h
+++ b/third_party/WebKit/public/web/WebFrame.h
@@ -244,16 +244,12 @@
   // The script gets its own global scope and its own prototypes for
   // intrinsic JavaScript objects (String, Array, and so-on). It also
   // gets its own wrappers for all DOM nodes and DOM constructors.
-  // extensionGroup is an embedder-provided specifier that controls which
-  // v8 extensions are loaded into the new context - see
-  // blink::registerExtension for the corresponding specifier.
   //
   // worldID must be > 0 (as 0 represents the main world).
   // worldID must be < EmbedderWorldIdLimit, high number used internally.
   virtual void executeScriptInIsolatedWorld(int worldID,
                                             const WebScriptSource* sources,
-                                            unsigned numSources,
-                                            int extensionGroup) = 0;
+                                            unsigned numSources) = 0;
 
   // Associates an isolated world (see above for description) with a security
   // origin. XMLHttpRequest instances used in that world will be considered
@@ -287,7 +283,6 @@
       int worldID,
       const WebScriptSource* sourcesIn,
       unsigned numSources,
-      int extensionGroup,
       WebVector<v8::Local<v8::Value>>* results) = 0;
 
   // Call the function with the given receiver and arguments, bypassing
diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h
index ce7d795..561057b 100644
--- a/third_party/WebKit/public/web/WebFrameClient.h
+++ b/third_party/WebKit/public/web/WebFrameClient.h
@@ -575,7 +575,6 @@
   // frame context.
   virtual void didCreateScriptContext(WebLocalFrame*,
                                       v8::Local<v8::Context>,
-                                      int extensionGroup,
                                       int worldId) {}
 
   // WebKit is about to release its reference to a v8 context for a frame.
diff --git a/third_party/WebKit/public/web/WebLocalFrame.h b/third_party/WebKit/public/web/WebLocalFrame.h
index 6feb12f..50f78f2b 100644
--- a/third_party/WebKit/public/web/WebLocalFrame.h
+++ b/third_party/WebKit/public/web/WebLocalFrame.h
@@ -219,7 +219,6 @@
       int worldID,
       const WebScriptSource* sourceIn,
       unsigned numSources,
-      int extensionGroup,
       bool userGesture,
       WebScriptExecutionCallback*) = 0;
 
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 41ece1a..63921188 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -53321,6 +53321,18 @@
   </summary>
 </histogram>
 
+<histogram name="ResourcePrefetchPredictor.DatabaseReadiness" units="%">
+  <owner>alexilin@chromium.org</owner>
+  <summary>
+    This metric measures the host coverage of the predictor database: On each
+    navigation, it records what percentage of the top X history entries are
+    found in the predictor DB. Caveats: (1) This metric is only recorded once
+    the user has accumulated enough browsing history, implemented as a minimum
+    threshold of total page visits by the user. (2) This metric is sampled, so
+    it's actually only recorded for 1 out of every K navigations.
+  </summary>
+</histogram>
+
 <histogram name="ResourcePrefetchPredictor.DbStringTooLong">
   <obsolete>
     Deprecated October 2016. No longer recorded.