diff --git a/.gitattributes b/.gitattributes
index 21a13a6..74328c4 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,7 +1,2 @@
-## This page intentionally left blank. ##
-#
-# Workaround for VS2013 automatically creating .gitattributes files with
-# default settings that we don't want.
-# See also:
-# http://connect.microsoft.com/VisualStudio/feedback/details/804948/inappropriately-creates-gitattributes-file
-# http://crbug.com/342064
+# Stop Windows python license check presubmit errors by forcing LF checkout.
+*.py  text eol=lf
diff --git a/AUTHORS b/AUTHORS
index a8dea032..4100e723 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -539,6 +539,7 @@
 Peter Gal <pgal.u-szeged@partner.samsung.com>
 Peter Molnar <pmolnar.u-szeged@partner.samsung.com>
 Philipp Hancke <fippo@andyet.net>
+Philipp Hancke <philipp.hancke@googlemail.com>
 Philippe Beauchamp <philippe.beauchamp@gmail.com>
 Philippe Beaudoin <philippe.beaudoin@gmail.com>
 Pierre-Antoine LaFayette <pierre.lafayette@gmail.com>
diff --git a/DEPS b/DEPS
index 71c53b27..434a7de 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '1ba626d657d1a2f2093ccd9ed415563c77c62b0a',
+  'v8_revision': '35e713ce9a5629d09b38019e0e5725bf43d018dd',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
diff --git a/OWNERS b/OWNERS
index 8102abb..fe90e901 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,6 +4,7 @@
 darin@chromium.org
 jam@chromium.org
 
+per-file .gitattributes=*
 per-file .gitignore=*
 per-file .git-blame-ignore-revs=mgiuca@chromium.org
 per-file .git-blame-ignore-revs=thakis@chromium.org
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 89c5b88..7acc3cea 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -597,6 +597,9 @@
     "java/src/org/chromium/android_webview/JsResultReceiver.java",
     "java/src/org/chromium/android_webview/NullAwViewMethods.java",
     "java/src/org/chromium/android_webview/OverScrollGlow.java",
+
+    # TODO(gsennton): remove PlatformServiceBridge after downstream has been updated to depend on
+    # android_webview_platform_services_java
     "java/src/org/chromium/android_webview/PlatformServiceBridge.java",
     "java/src/org/chromium/android_webview/PopupTouchHandleDrawable.java",
     "java/src/org/chromium/android_webview/ResourcesContextWrapperFactory.java",
@@ -681,6 +684,17 @@
   ]
 }
 
+# Separate target to allow for a dependency on GmsCore without pulling in all of
+# android_webview_java.
+android_library("android_webview_platform_services_java") {
+  java_files =
+      [ "java/src/org/chromium/android_webview/PlatformServiceBridge.java" ]
+
+  deps = [
+    "//base:base_java",
+  ]
+}
+
 if (!use_webview_internal_framework) {
   system_webview_apk_tmpl("system_webview_apk") {
     android_manifest = system_webview_android_manifest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java
index 5c243dc..4819abb1 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java
@@ -9,6 +9,7 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.autofill.AutofillTestHelper;
@@ -52,8 +53,9 @@
     }
 
     /** Attempt to add invalid contact information and cancel the transaction. */
-    @MediumTest
-    @Feature({"Payments"})
+    // @MediumTest
+    // @Feature({"Payments"})
+    @DisabledTest
     public void testAddInvalidContactAndCancel()
             throws InterruptedException, ExecutionException, TimeoutException {
         triggerUIAndWait(mReadyToPay);
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 2c03a0d9..82f34fa7 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -11251,7 +11251,7 @@
         Google may use your browsing history to personalize Search, ads, and other Google services
       </message>
       <message name="IDS_SYNC_CONFIRMATION_SYNC_SETTINGS_LINK_BODY" desc="Label of the section containing the link to go to the sync setting page.">
-        Control how this works in <ph name="BEGIN_LINK">&lt;a id="settingsLink" href="#"&gt;Settings&lt;/a&gt;.</ph>
+        Control how this works in <ph name="BEGIN_LINK">&lt;a id="settingsLink" href="#"&gt;</ph>Settings<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>
       </message>
       <message name="IDS_SYNC_CONFIRMATION_CONFIRM_BUTTON_LABEL" desc="Label of the confirmation button in the sync confirmation dialog of the tab modal signin flow">
         Ok, got it
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
index 91e3d93..c47ea93c 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
@@ -91,20 +91,44 @@
 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary;
 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary;
 
-std::vector<URLRequestSummary> GetUniqueSubresources(
-    const PageRequestSummary& summary) {
-  std::vector<URLRequestSummary> subresources(summary.subresource_requests);
-  std::stable_sort(subresources.begin(), subresources.end(),
+void RemoveDuplicateSubresources(std::vector<URLRequestSummary>* subresources) {
+  std::stable_sort(subresources->begin(), subresources->end(),
                    [](const URLRequestSummary& x, const URLRequestSummary& y) {
                      return x.resource_url < y.resource_url;
                    });
-  subresources.erase(
-      std::unique(subresources.begin(), subresources.end(),
+  subresources->erase(
+      std::unique(subresources->begin(), subresources->end(),
                   [](const URLRequestSummary& x, const URLRequestSummary& y) {
                     return x.resource_url == y.resource_url;
                   }),
-      subresources.end());
-  return subresources;
+      subresources->end());
+}
+
+// Fill a NavigationID with "empty" data that does not trigger
+// the is_valid DCHECK(). Allows comparing.
+void SetValidNavigationID(NavigationID* navigation_id) {
+  navigation_id->render_process_id = 0;
+  navigation_id->render_frame_id = 0;
+  navigation_id->main_frame_url = GURL("http://127.0.0.1");
+}
+
+// Does a custom comparison of subresources of URLRequestSummary
+// and fail the test if the expectation is not met.
+void CompareSubresources(std::vector<URLRequestSummary> actual_subresources,
+                         std::vector<URLRequestSummary> expected_subresources,
+                         bool match_navigation_id) {
+  // Duplicate resources can be observed in a single navigation but
+  // ResourcePrefetchPredictor only cares about the first occurrence of each.
+  RemoveDuplicateSubresources(&actual_subresources);
+
+  if (!match_navigation_id) {
+    for (auto& subresource : actual_subresources)
+      SetValidNavigationID(&subresource.navigation_id);
+    for (auto& subresource : expected_subresources)
+      SetValidNavigationID(&subresource.navigation_id);
+  }
+  EXPECT_THAT(actual_subresources,
+              testing::UnorderedElementsAreArray(expected_subresources));
 }
 
 }  // namespace
@@ -119,10 +143,12 @@
   explicit ResourcePrefetchPredictorTestObserver(
       ResourcePrefetchPredictor* predictor,
       const size_t expected_url_visit_count,
-      const PageRequestSummary& expected_summary)
+      const PageRequestSummary& expected_summary,
+      bool match_navigation_id)
       : TestObserver(predictor),
         url_visit_count_(expected_url_visit_count),
-        summary_(expected_summary) {}
+        summary_(expected_summary),
+        match_navigation_id_(match_navigation_id) {}
 
   // TestObserver:
   void OnNavigationLearned(size_t url_visit_count,
@@ -130,12 +156,8 @@
     EXPECT_EQ(url_visit_count, url_visit_count_);
     EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url);
     EXPECT_EQ(summary.initial_url, summary_.initial_url);
-    // Duplicate resources can be observed in a single navigation but
-    // ResourcePrefetchPredictor only cares about the first occurrence of each.
-    std::vector<ResourcePrefetchPredictor::URLRequestSummary> subresources =
-        GetUniqueSubresources(summary);
-    EXPECT_THAT(subresources, testing::UnorderedElementsAreArray(
-                                  summary_.subresource_requests));
+    CompareSubresources(summary.subresource_requests,
+                        summary_.subresource_requests, match_navigation_id_);
     run_loop_.Quit();
   }
 
@@ -145,6 +167,7 @@
   base::RunLoop run_loop_;
   size_t url_visit_count_;
   PageRequestSummary summary_;
+  bool match_navigation_id_;
 
   DISALLOW_COPY_AND_ASSIGN(ResourcePrefetchPredictorTestObserver);
 };
@@ -173,7 +196,9 @@
     EnsurePredictorInitialized();
   }
 
-  void NavigateToURLAndCheckSubresources(const GURL& main_frame_url) {
+  void NavigateToURLAndCheckSubresources(
+      const GURL& main_frame_url,
+      WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB) {
     GURL endpoint_url = GetRedirectEndpoint(main_frame_url);
     std::vector<URLRequestSummary> url_request_summaries;
     for (const auto& kv : resources_) {
@@ -185,8 +210,11 @@
     ResourcePrefetchPredictorTestObserver observer(
         predictor_, UpdateAndGetVisitCount(main_frame_url),
         CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(),
-                                 url_request_summaries));
-    ui_test_utils::NavigateToURL(browser(), main_frame_url);
+                                 url_request_summaries),
+        true);  // Matching navigation id by default
+    ui_test_utils::NavigateToURLWithDisposition(
+        browser(), main_frame_url, disposition,
+        ui_test_utils::BROWSER_TEST_NONE);
     observer.Wait();
   }
 
diff --git a/chrome/browser/resources/snippets_internals.html b/chrome/browser/resources/snippets_internals.html
index acfa350f..0e4ff0b 100644
--- a/chrome/browser/resources/snippets_internals.html
+++ b/chrome/browser/resources/snippets_internals.html
@@ -6,8 +6,7 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
 <if expr="is_android or is_ios">
-<meta name="viewport" content="width=device-width, initial-scale=1.0,
-    maximum-scale=1.0, user-scalable=no">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
 </if>
 <title>Snippets Internals</title>
 <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc
index 1761130..335905e 100644
--- a/chrome/browser/search/search_unittest.cc
+++ b/chrome/browser/search/search_unittest.cc
@@ -443,6 +443,7 @@
   std::map<std::string, bool> hosts;
   hosts["foo.com"] = false;
   url_filter->SetManualHosts(&hosts);
+  url_filter->SetEnabled(true);
 
   EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
             GetNewTabPageURL(profile()));
diff --git a/chrome/browser/supervised_user/supervised_user_resource_throttle.cc b/chrome/browser/supervised_user/supervised_user_resource_throttle.cc
index a0695f62..53df77ad 100644
--- a/chrome/browser/supervised_user/supervised_user_resource_throttle.cc
+++ b/chrome/browser/supervised_user/supervised_user_resource_throttle.cc
@@ -117,7 +117,7 @@
     const SupervisedUserURLFilter* url_filter) {
   // Only treat main frame requests (ignoring subframes and subresources).
   bool is_main_frame = resource_type == content::RESOURCE_TYPE_MAIN_FRAME;
-  if (!is_main_frame)
+  if (!is_main_frame || !url_filter->enabled())
     return nullptr;
 
   // Can't use base::MakeUnique because the constructor is private.
diff --git a/chrome/browser/supervised_user/supervised_user_resource_throttle_browsertest.cc b/chrome/browser/supervised_user/supervised_user_resource_throttle_browsertest.cc
index c19e8d29..90955a67 100644
--- a/chrome/browser/supervised_user/supervised_user_resource_throttle_browsertest.cc
+++ b/chrome/browser/supervised_user/supervised_user_resource_throttle_browsertest.cc
@@ -136,3 +136,28 @@
   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(tab, "loaded2()", &loaded2));
   EXPECT_TRUE(loaded2);
 }
+
+class SupervisedUserResourceThrottleNotSupervisedTest
+    : public SupervisedUserResourceThrottleTest {
+ protected:
+  SupervisedUserResourceThrottleNotSupervisedTest() {}
+  ~SupervisedUserResourceThrottleNotSupervisedTest() override {}
+
+ private:
+  // Overridden to do nothing, so that the supervised user ID will be empty.
+  void SetUpCommandLine(base::CommandLine* command_line) override {}
+};
+
+IN_PROC_BROWSER_TEST_F(SupervisedUserResourceThrottleNotSupervisedTest,
+                       DontBlock) {
+  BlockHost(kExampleHost);
+
+  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
+
+  GURL blocked_url = embedded_test_server()->GetURL(
+      kExampleHost, "/supervised_user/simple.html");
+  ui_test_utils::NavigateToURL(browser(), blocked_url);
+  // Even though the URL is marked as blocked, the load should go through, since
+  // the user isn't supervised.
+  EXPECT_FALSE(tab->ShowingInterstitialPage());
+}
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc
index 324f525d6..a470f3e 100644
--- a/chrome/browser/supervised_user/supervised_user_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -441,6 +441,13 @@
   return io_url_filter_.get();
 }
 
+void SupervisedUserService::URLFilterContext::SetEnabled(bool enabled) {
+  ui_url_filter_->SetEnabled(enabled);
+  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+                          base::Bind(&SupervisedUserURLFilter::SetEnabled,
+                                     io_url_filter_, enabled));
+}
+
 void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
     SupervisedUserURLFilter::FilteringBehavior behavior) {
   ui_url_filter_->SetDefaultFilteringBehavior(behavior);
@@ -672,6 +679,8 @@
     BrowserList::RemoveObserver(this);
 #endif
   }
+
+  url_filter_context_.SetEnabled(active_);
 }
 
 #if !defined(OS_ANDROID)
diff --git a/chrome/browser/supervised_user/supervised_user_service.h b/chrome/browser/supervised_user/supervised_user_service.h
index b896f63a5..b461177 100644
--- a/chrome/browser/supervised_user/supervised_user_service.h
+++ b/chrome/browser/supervised_user/supervised_user_service.h
@@ -250,6 +250,7 @@
     SupervisedUserURLFilter* ui_url_filter() const;
     SupervisedUserURLFilter* io_url_filter() const;
 
+    void SetEnabled(bool enabled);
     void SetDefaultFilteringBehavior(
         SupervisedUserURLFilter::FilteringBehavior behavior);
     void LoadWhitelists(
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.cc b/chrome/browser/supervised_user/supervised_user_url_filter.cc
index 5318b1b..dfece48 100644
--- a/chrome/browser/supervised_user/supervised_user_url_filter.cc
+++ b/chrome/browser/supervised_user/supervised_user_url_filter.cc
@@ -231,7 +231,8 @@
 }  // namespace
 
 SupervisedUserURLFilter::SupervisedUserURLFilter()
-    : default_behavior_(ALLOW),
+    : enabled_(false),
+      default_behavior_(ALLOW),
       contents_(new Contents()),
       blacklist_(nullptr),
       amp_cache_path_regex_(kAmpCachePathPattern),
@@ -323,6 +324,16 @@
   return trimmed_host == trimmed_pattern;
 }
 
+void SupervisedUserURLFilter::SetEnabled(bool enabled) {
+  if (enabled_ == enabled)
+    return;
+
+  enabled_ = enabled;
+
+  for (Observer& observer : observers_)
+    observer.OnSiteListUpdated();
+}
+
 SupervisedUserURLFilter::FilteringBehavior
 SupervisedUserURLFilter::GetFilteringBehaviorForURL(const GURL& url) const {
   supervised_user_error_page::FilteringBehaviorReason reason;
@@ -343,6 +354,11 @@
     supervised_user_error_page::FilteringBehaviorReason* reason) const {
   DCHECK(CalledOnValidThread());
 
+  if (!enabled_) {
+    *reason = supervised_user_error_page::DEFAULT;
+    return ALLOW;
+  }
+
   GURL effective_url = GetEmbeddedURL(url);
   if (!effective_url.is_valid())
     effective_url = url;
@@ -645,8 +661,10 @@
 void SupervisedUserURLFilter::SetContents(std::unique_ptr<Contents> contents) {
   DCHECK(CalledOnValidThread());
   contents_ = std::move(contents);
-  for (Observer& observer : observers_)
-    observer.OnSiteListUpdated();
+  if (enabled_) {
+    for (Observer& observer : observers_)
+      observer.OnSiteListUpdated();
+  }
 }
 
 void SupervisedUserURLFilter::CheckCallback(
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.h b/chrome/browser/supervised_user/supervised_user_url_filter.h
index 0b34d37..e11c50cc 100644
--- a/chrome/browser/supervised_user/supervised_user_url_filter.h
+++ b/chrome/browser/supervised_user/supervised_user_url_filter.h
@@ -61,7 +61,11 @@
 
   class Observer {
    public:
+    // Called whenever the filter changes.
+    // TODO(treib,bauerb): Rename to OnURLFilterUpdated.
     virtual void OnSiteListUpdated() = 0;
+    // Called whenever a check started via
+    // GetFilteringBehaviorForURLWithAsyncChecks completes.
     virtual void OnURLChecked(
         const GURL& url,
         FilteringBehavior behavior,
@@ -106,6 +110,13 @@
   static bool HostMatchesPattern(const std::string& canonical_host,
                                  const std::string& pattern);
 
+  // Returns whether the filter is enabled. If this is false, all URL checks
+  // will return ALLOW.
+  bool enabled() const { return enabled_; }
+
+  // Enables or disables the filter. Notifies observers if the state changed.
+  void SetEnabled(bool enabled);
+
   // Returns the filtering behavior for a given URL, based on the default
   // behavior and whether it is on a site list.
   FilteringBehavior GetFilteringBehaviorForURL(const GURL& url) const;
@@ -198,6 +209,10 @@
   // This is mutable to allow notification in const member functions.
   mutable base::ObserverList<Observer> observers_;
 
+  // Whether this filter is enabled. True for supervised user profiles, false
+  // otherwise.
+  bool enabled_;
+
   FilteringBehavior default_behavior_;
   std::unique_ptr<Contents> contents_;
 
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter_unittest.cc b/chrome/browser/supervised_user/supervised_user_url_filter_unittest.cc
index e306abc..bbac7bae 100644
--- a/chrome/browser/supervised_user/supervised_user_url_filter_unittest.cc
+++ b/chrome/browser/supervised_user/supervised_user_url_filter_unittest.cc
@@ -22,6 +22,7 @@
  public:
   SupervisedUserURLFilterTest() : filter_(new SupervisedUserURLFilter) {
     filter_->SetDefaultFilteringBehavior(SupervisedUserURLFilter::BLOCK);
+    filter_->SetEnabled(true);
     filter_->AddObserver(this);
   }
 
@@ -68,6 +69,11 @@
   EXPECT_TRUE(IsURLWhitelisted("chrome://extensions/"));
   EXPECT_TRUE(IsURLWhitelisted("chrome-extension://foo/main.html"));
   EXPECT_TRUE(IsURLWhitelisted("file:///home/chronos/user/Downloads/img.jpg"));
+
+  // If the filter is disabled, everything should be allowed.
+  filter_->SetEnabled(false);
+  EXPECT_TRUE(IsURLWhitelisted("http://google.com"));
+  EXPECT_TRUE(IsURLWhitelisted("http://notgoogle.com/"));
 }
 
 TEST_F(SupervisedUserURLFilterTest, EffectiveURL) {
diff --git a/components/ntp_snippets/remote/ntp_snippets_fetcher.cc b/components/ntp_snippets/remote/ntp_snippets_fetcher.cc
index 76ec5f1e..360d476 100644
--- a/components/ntp_snippets/remote/ntp_snippets_fetcher.cc
+++ b/components/ntp_snippets/remote/ntp_snippets_fetcher.cc
@@ -4,6 +4,7 @@
 
 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h"
 
+#include <algorithm>
 #include <cstdlib>
 #include <utility>
 
@@ -61,6 +62,9 @@
 // Variation parameter for personalizing fetching of snippets.
 const char kPersonalizationName[] = "fetching_personalization";
 
+// Variation parameter for disabling the retry.
+const char kBackground5xxRetriesName[] = "background_5xx_retries_count";
+
 // Variation parameter for chrome-content-suggestions backend.
 const char kContentSuggestionsBackend[] = "content_suggestions_backend";
 
@@ -132,6 +136,15 @@
   return default_value;
 }
 
+int Get5xxRetryCount(bool interactive_request) {
+  if (interactive_request) {
+    return 2;
+  }
+  return std::max(0, variations::GetVariationParamByFeatureAsInt(
+                         ntp_snippets::kArticleSuggestionsFeature,
+                         kBackground5xxRetriesName, 0));
+}
+
 bool UsesChromeContentSuggestionsAPI(const GURL& endpoint) {
   if (endpoint == kChromeReaderServer) {
     return false;
@@ -812,8 +825,8 @@
 
   // Fetchers are sometimes cancelled because a network change was detected.
   url_fetcher->SetAutomaticallyRetryOnNetworkChanges(3);
-  // Try to make fetching the files bit more robust even with poor connection.
-  url_fetcher->SetMaxRetriesOn5xx(3);
+  url_fetcher->SetMaxRetriesOn5xx(
+      Get5xxRetryCount(params_.interactive_request));
   return url_fetcher;
 }
 
diff --git a/components/ntp_snippets/remote/ntp_snippets_fetcher.h b/components/ntp_snippets/remote/ntp_snippets_fetcher.h
index 772aa05..92a2343 100644
--- a/components/ntp_snippets/remote/ntp_snippets_fetcher.h
+++ b/components/ntp_snippets/remote/ntp_snippets_fetcher.h
@@ -224,6 +224,10 @@
         const scoped_refptr<net::URLRequestContextGetter>& context_getter);
     RequestBuilder& SetUserClassifier(const UserClassifier& user_classifier);
 
+    // These preview methods allow to inspect the Request without exposing it
+    // publicly.
+    // TODO(fhorschig): Remove these when moving the RequestBuilder to
+    // snippets::internal and trigger the request to intercept the request.
     std::string PreviewRequestBodyForTesting() { return BuildBody(); }
     std::string PreviewRequestHeadersForTesting() { return BuildHeaders(); }
     RequestBuilder& SetUserClassForTesting(const std::string& user_class) {
diff --git a/components/ntp_snippets/remote/ntp_snippets_fetcher_unittest.cc b/components/ntp_snippets/remote/ntp_snippets_fetcher_unittest.cc
index dde8e381..88f85c43 100644
--- a/components/ntp_snippets/remote/ntp_snippets_fetcher_unittest.cc
+++ b/components/ntp_snippets/remote/ntp_snippets_fetcher_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h"
 
+#include <deque>
 #include <map>
 #include <utility>
 
@@ -16,6 +17,7 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "components/ntp_snippets/category_factory.h"
+#include "components/ntp_snippets/features.h"
 #include "components/ntp_snippets/ntp_snippets_constants.h"
 #include "components/ntp_snippets/remote/ntp_snippet.h"
 #include "components/ntp_snippets/user_classifier.h"
@@ -160,6 +162,83 @@
            NTPSnippetsFetcher::OptionalFetchedCategories* fetched_categories));
 };
 
+// TODO(fhorschig): Transfer this class' functionality to call delegates
+// automatically as option to TestURLFetcherFactory where it was just deleted.
+// This can be represented as a single member there and would reduce the amount
+// of fake implementations from three to two.
+
+// DelegateCallingTestURLFetcherFactory can be used to temporarily inject
+// TestURLFetcher instances into a scope.
+// Client code can access the last created fetcher to verify expected
+// properties. When the factory gets destroyed, all available delegates of still
+// valid fetchers will be called.
+// This ensures once-bound callbacks (like SnippetsAvailableCallback) will be
+// called at some point and are not leaked.
+class DelegateCallingTestURLFetcherFactory
+    : public net::TestURLFetcherFactory,
+      public net::TestURLFetcherDelegateForTests {
+ public:
+  DelegateCallingTestURLFetcherFactory() {
+    SetDelegateForTests(this);
+    set_remove_fetcher_on_delete(true);
+  }
+
+  ~DelegateCallingTestURLFetcherFactory() override {
+    while (!fetchers_.empty()) {
+      DropAndCallDelegate(fetchers_.front());
+    }
+  }
+
+  std::unique_ptr<net::URLFetcher> CreateURLFetcher(
+      int id,
+      const GURL& url,
+      net::URLFetcher::RequestType request_type,
+      net::URLFetcherDelegate* d) override {
+    if (GetFetcherByID(id)) {
+      LOG(WARNING) << "The ID " << id << " was already assigned to a fetcher."
+                   << "Its delegate will thereforde be called right now.";
+      DropAndCallDelegate(id);
+    }
+    fetchers_.push_back(id);
+    return TestURLFetcherFactory::CreateURLFetcher(id, url, request_type, d);
+  }
+
+  // Returns the raw pointer of the last created URL fetcher.
+  // If it was destroyed or no fetcher was created, it will return a nulltpr.
+  net::TestURLFetcher* GetLastCreatedFetcher() {
+    if (fetchers_.empty()) {
+      return nullptr;
+    }
+    return GetFetcherByID(fetchers_.front());
+  }
+
+ private:
+  // The fetcher can either be destroyed because the delegate was called during
+  // execution or because we called it on destruction.
+  void DropAndCallDelegate(int fetcher_id) {
+    auto found_id_iter =
+        std::find(fetchers_.begin(), fetchers_.end(), fetcher_id);
+    if (found_id_iter == fetchers_.end()) {
+      return;
+    }
+    fetchers_.erase(found_id_iter);
+    net::TestURLFetcher* fetcher = GetFetcherByID(fetcher_id);
+    if (!fetcher->delegate()) {
+      return;
+    }
+    fetcher->delegate()->OnURLFetchComplete(fetcher);
+  }
+
+  // net::TestURLFetcherDelegateForTests overrides:
+  void OnRequestStart(int fetcher_id) override {}
+  void OnChunkUpload(int fetcher_id) override {}
+  void OnRequestEnd(int fetcher_id) override {
+    DropAndCallDelegate(fetcher_id);
+  }
+
+  std::deque<int> fetchers_;  // std::queue doesn't support std::find.
+};
+
 // Factory for FakeURLFetcher objects that always generate errors.
 class FailingFakeURLFetcherFactory : public net::URLFetcherFactory {
  public:
@@ -292,6 +371,15 @@
             ntp_snippets::kStudyName, params);
   }
 
+  void SetVariationParametersForFeatures(
+      const std::map<std::string, std::string>& params,
+      const std::set<std::string>& features) {
+    params_manager_.reset();
+    params_manager_ =
+        base::MakeUnique<variations::testing::VariationParamsManager>(
+            ntp_snippets::kStudyName, params, features);
+  }
+
   void SetFakeResponse(const std::string& response_data,
                        net::HttpStatusCode response_code,
                        net::URLRequestStatus::Status status) {
@@ -912,13 +1000,15 @@
 }
 
 TEST_F(NTPSnippetsFetcherTest, ShouldRestrictToHosts) {
-  net::TestURLFetcherFactory test_url_fetcher_factory;
+  DelegateCallingTestURLFetcherFactory fetcher_factory;
   NTPSnippetsFetcher::Params params = test_params();
   params.hosts = {"www.somehost1.com", "www.somehost2.com"};
   params.count_to_fetch = 17;
+
   snippets_fetcher().FetchSnippets(
       params, ToSnippetsAvailableCallback(&mock_callback()));
-  net::TestURLFetcher* fetcher = test_url_fetcher_factory.GetFetcherByID(0);
+
+  net::TestURLFetcher* fetcher = fetcher_factory.GetLastCreatedFetcher();
   ASSERT_THAT(fetcher, NotNull());
   std::unique_ptr<base::Value> value =
       base::JSONReader::Read(fetcher->upload_data());
@@ -941,19 +1031,50 @@
   ASSERT_TRUE(content_selectors->GetDictionary(1, &content_selector));
   EXPECT_TRUE(content_selector->GetString("value", &content_selector_value));
   EXPECT_THAT(content_selector_value, Eq("www.somehost2.com"));
-  // Call the delegate callback manually as the TestURLFetcher deletes any
-  // call to the delegate that usually happens on |Start|.
-  // Without the call to the delegate, it leaks the request that owns itself.
-  ASSERT_THAT(fetcher->delegate(), NotNull());
-  EXPECT_CALL(mock_callback(),
-              Run(NTPSnippetsFetcher::FetchResult::URL_REQUEST_STATUS_ERROR,
-                  /*snippets=*/Not(HasValue())))
-      .Times(1);
-  // An 4XX response needs the least configuration to successfully invoke the
-  // callback properly as the results are not important in this test.
-  fetcher->set_response_code(net::HTTP_NOT_FOUND);
-  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, -2));
-  fetcher->delegate()->OnURLFetchComplete(fetcher);
+}
+
+TEST_F(NTPSnippetsFetcherTest, RetryOnInteractiveRequests) {
+  DelegateCallingTestURLFetcherFactory fetcher_factory;
+  NTPSnippetsFetcher::Params params = test_params();
+  params.interactive_request = true;
+
+  snippets_fetcher().FetchSnippets(
+      params, ToSnippetsAvailableCallback(&mock_callback()));
+
+  net::TestURLFetcher* fetcher = fetcher_factory.GetLastCreatedFetcher();
+  ASSERT_THAT(fetcher, NotNull());
+  EXPECT_THAT(fetcher->GetMaxRetriesOn5xx(), Eq(2));
+}
+
+TEST_F(NTPSnippetsFetcherTest, RetriesConfigurableOnNonInteractiveRequests) {
+  struct ExpectationForVariationParam {
+    std::string param_value;
+    int expected_value;
+    std::string description;
+  };
+  const std::vector<ExpectationForVariationParam> retry_config_expectation = {
+      {"", 0, "Do not retry by default"},
+      {"0", 0, "Do not retry on param value 0"},
+      {"-1", 0, "Do not retry on negative param values."},
+      {"4", 4, "Retry as set in param value."}};
+
+  NTPSnippetsFetcher::Params params = test_params();
+  params.interactive_request = false;
+
+  for (const auto& retry_config : retry_config_expectation) {
+    DelegateCallingTestURLFetcherFactory fetcher_factory;
+    SetVariationParametersForFeatures(
+        {{"background_5xx_retries_count", retry_config.param_value}},
+        {ntp_snippets::kArticleSuggestionsFeature.name});
+
+    snippets_fetcher().FetchSnippets(
+        params, ToSnippetsAvailableCallback(&mock_callback()));
+
+    net::TestURLFetcher* fetcher = fetcher_factory.GetLastCreatedFetcher();
+    ASSERT_THAT(fetcher, NotNull());
+    EXPECT_THAT(fetcher->GetMaxRetriesOn5xx(), Eq(retry_config.expected_value))
+        << retry_config.description;
+  }
 }
 
 TEST_F(NTPSnippetsFetcherTest, ShouldReportUrlStatusError) {
diff --git a/components/ntp_tiles/webui/resources/popular_sites_internals.html b/components/ntp_tiles/webui/resources/popular_sites_internals.html
index d82e0940..81d8145 100644
--- a/components/ntp_tiles/webui/resources/popular_sites_internals.html
+++ b/components/ntp_tiles/webui/resources/popular_sites_internals.html
@@ -8,8 +8,7 @@
 <head>
 <meta charset="utf-8">
 <if expr="is_android or is_ios">
-<meta name="viewport" content="width=device-width, initial-scale=1.0,
-                               maximum-scale=1.0, user-scalable=no">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
 </if>
 <title>Popular Sites Internals</title>
 <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 7e20f95..5516a44 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -956,10 +956,8 @@
     "notifications/platform_notification_context_impl.h",
     "notifications/type_converters.cc",
     "notifications/type_converters.h",
-    "payments/payment_app_context_impl.cc",
-    "payments/payment_app_context_impl.h",
-    "payments/payment_app_database.cc",
-    "payments/payment_app_database.h",
+    "payments/payment_app_context.cc",
+    "payments/payment_app_context.h",
     "payments/payment_app_manager.cc",
     "payments/payment_app_manager.h",
     "permissions/permission_service_context.cc",
diff --git a/content/browser/payments/payment_app_context.cc b/content/browser/payments/payment_app_context.cc
new file mode 100644
index 0000000..8fc961a52
--- /dev/null
+++ b/content/browser/payments/payment_app_context.cc
@@ -0,0 +1,69 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/payments/payment_app_context.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "base/stl_util.h"
+#include "content/browser/payments/payment_app_manager.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+PaymentAppContext::PaymentAppContext(
+    scoped_refptr<ServiceWorkerContextWrapper> service_worker_context)
+    : service_worker_context_(std::move(service_worker_context)) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+}
+
+PaymentAppContext::~PaymentAppContext() {
+  DCHECK(services_.empty());
+}
+
+void PaymentAppContext::Shutdown() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+                          base::Bind(&PaymentAppContext::ShutdownOnIO, this));
+}
+
+void PaymentAppContext::CreateService(
+    mojo::InterfaceRequest<payments::mojom::PaymentAppManager> request) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::Bind(&PaymentAppContext::CreateServiceOnIOThread, this,
+                 base::Passed(&request)));
+}
+
+void PaymentAppContext::ServiceHadConnectionError(PaymentAppManager* service) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(base::ContainsKey(services_, service));
+
+  services_.erase(service);
+}
+
+ServiceWorkerContextWrapper* PaymentAppContext::service_worker_context() const {
+  return service_worker_context_.get();
+}
+
+void PaymentAppContext::CreateServiceOnIOThread(
+    mojo::InterfaceRequest<payments::mojom::PaymentAppManager> request) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  PaymentAppManager* service = new PaymentAppManager(this, std::move(request));
+  services_[service] = base::WrapUnique(service);
+}
+
+void PaymentAppContext::ShutdownOnIO() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  services_.clear();
+}
+
+}  // namespace content
diff --git a/content/browser/payments/payment_app_context.h b/content/browser/payments/payment_app_context.h
new file mode 100644
index 0000000..3572a8b
--- /dev/null
+++ b/content/browser/payments/payment_app_context.h
@@ -0,0 +1,64 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_CONTEXT_H_
+#define CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_CONTEXT_H_
+
+#include <map>
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "components/payments/payment_app.mojom.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class PaymentAppManager;
+class ServiceWorkerContextWrapper;
+
+class CONTENT_EXPORT PaymentAppContext
+    : public base::RefCountedThreadSafe<PaymentAppContext> {
+ public:
+  explicit PaymentAppContext(
+      scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
+
+  // Shutdown must be called before deleting this. Call on the UI thread.
+  void Shutdown();
+
+  // Create a PaymentAppManager that is owned by this. Call on the UI
+  // thread.
+  void CreateService(
+      mojo::InterfaceRequest<payments::mojom::PaymentAppManager> request);
+
+  // Called by PaymentAppManager objects so that they can
+  // be deleted. Call on the IO thread.
+  void ServiceHadConnectionError(PaymentAppManager* service);
+
+  ServiceWorkerContextWrapper* service_worker_context() const;
+
+ protected:
+  friend class base::RefCountedThreadSafe<PaymentAppContext>;
+  friend class PaymentAppManagerTest;
+  virtual ~PaymentAppContext();
+
+ private:
+  void CreateServiceOnIOThread(
+      mojo::InterfaceRequest<payments::mojom::PaymentAppManager> request);
+
+  void ShutdownOnIO();
+
+  scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
+
+  // The services are owned by this. They're either deleted
+  // during ShutdownOnIO or when the channel is closed via
+  // ServiceHadConnectionError. Only accessed on the IO thread.
+  std::map<PaymentAppManager*, std::unique_ptr<PaymentAppManager>> services_;
+
+  DISALLOW_COPY_AND_ASSIGN(PaymentAppContext);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_CONTEXT_H_
diff --git a/content/browser/payments/payment_app_context_impl.cc b/content/browser/payments/payment_app_context_impl.cc
deleted file mode 100644
index e2a84e62..0000000
--- a/content/browser/payments/payment_app_context_impl.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/payments/payment_app_context_impl.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/memory/ptr_util.h"
-#include "base/stl_util.h"
-#include "content/browser/payments/payment_app_database.h"
-#include "content/browser/payments/payment_app_manager.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace content {
-
-PaymentAppContextImpl::PaymentAppContextImpl() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-}
-
-void PaymentAppContextImpl::Init(
-    scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::Bind(&PaymentAppContextImpl::CreatePaymentAppDatabaseOnIO, this,
-                 service_worker_context));
-}
-
-void PaymentAppContextImpl::Shutdown() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::Bind(&PaymentAppContextImpl::ShutdownOnIO, this));
-}
-
-void PaymentAppContextImpl::CreateService(
-    mojo::InterfaceRequest<payments::mojom::PaymentAppManager> request) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::Bind(&PaymentAppContextImpl::CreateServiceOnIOThread, this,
-                 base::Passed(&request)));
-}
-
-void PaymentAppContextImpl::ServiceHadConnectionError(
-    PaymentAppManager* service) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DCHECK(base::ContainsKey(services_, service));
-
-  services_.erase(service);
-}
-
-PaymentAppDatabase* PaymentAppContextImpl::payment_app_database() const {
-  return payment_app_database_.get();
-}
-
-void PaymentAppContextImpl::GetAllManifests(
-    const GetAllManifestsCallback& callback) {
-  NOTIMPLEMENTED();
-}
-
-PaymentAppContextImpl::~PaymentAppContextImpl() {
-  DCHECK(services_.empty());
-  DCHECK(!payment_app_database_);
-}
-
-void PaymentAppContextImpl::CreatePaymentAppDatabaseOnIO(
-    scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  payment_app_database_ =
-      base::WrapUnique(new PaymentAppDatabase(service_worker_context));
-}
-
-void PaymentAppContextImpl::CreateServiceOnIOThread(
-    mojo::InterfaceRequest<payments::mojom::PaymentAppManager> request) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  PaymentAppManager* service = new PaymentAppManager(this, std::move(request));
-  services_[service] = base::WrapUnique(service);
-}
-
-void PaymentAppContextImpl::ShutdownOnIO() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  services_.clear();
-  payment_app_database_.reset();
-}
-
-}  // namespace content
diff --git a/content/browser/payments/payment_app_context_impl.h b/content/browser/payments/payment_app_context_impl.h
deleted file mode 100644
index 79a85a6..0000000
--- a/content/browser/payments/payment_app_context_impl.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_CONTEXT_IMPL_H_
-#define CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_CONTEXT_IMPL_H_
-
-#include <map>
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "components/payments/payment_app.mojom.h"
-#include "content/browser/payments/payment_app_database.h"
-#include "content/common/content_export.h"
-#include "content/public/browser/payment_app_context.h"
-
-namespace content {
-
-class PaymentAppManager;
-
-class CONTENT_EXPORT PaymentAppContextImpl
-    : NON_EXPORTED_BASE(public PaymentAppContext),
-      public base::RefCountedThreadSafe<PaymentAppContextImpl> {
- public:
-  PaymentAppContextImpl();
-
-  // Init and Shutdown are for use on the UI thread when the
-  // StoragePartition is being setup and torn down.
-  void Init(scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
-
-  // Shutdown must be called before deleting this. Call on the UI thread.
-  void Shutdown();
-
-  // Create a PaymentAppManager that is owned by this. Call on the UI
-  // thread.
-  void CreateService(
-      mojo::InterfaceRequest<payments::mojom::PaymentAppManager> request);
-
-  // Called by PaymentAppManager objects so that they can
-  // be deleted. Call on the IO thread.
-  void ServiceHadConnectionError(PaymentAppManager* service);
-
-  PaymentAppDatabase* payment_app_database() const;
-
-  void GetAllManifests(const GetAllManifestsCallback& callback) override;
-
- protected:
-  friend class base::RefCountedThreadSafe<PaymentAppContextImpl>;
-  friend class PaymentAppManagerTest;
-  virtual ~PaymentAppContextImpl();
-
- private:
-  void CreatePaymentAppDatabaseOnIO(
-      scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
-
-  void CreateServiceOnIOThread(
-      mojo::InterfaceRequest<payments::mojom::PaymentAppManager> request);
-
-  void ShutdownOnIO();
-
-  // Only accessed on the IO thread.
-  std::unique_ptr<PaymentAppDatabase> payment_app_database_;
-
-  // The services are owned by this. They're either deleted
-  // during ShutdownOnIO or when the channel is closed via
-  // ServiceHadConnectionError. Only accessed on the IO thread.
-  std::map<PaymentAppManager*, std::unique_ptr<PaymentAppManager>> services_;
-
-  DISALLOW_COPY_AND_ASSIGN(PaymentAppContextImpl);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_CONTEXT_IMPL_H_
diff --git a/content/browser/payments/payment_app_database.cc b/content/browser/payments/payment_app_database.cc
deleted file mode 100644
index 9f18a2dc2..0000000
--- a/content/browser/payments/payment_app_database.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/payments/payment_app_database.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/optional.h"
-#include "content/browser/payments/payment_app.pb.h"
-#include "content/browser/payments/payment_app_context_impl.h"
-#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace content {
-namespace {
-
-const char kPaymentAppManifestDataKey[] = "PaymentAppManifestData";
-
-payments::mojom::PaymentAppManifestPtr DeserializePaymentAppManifest(
-    const std::string& input) {
-  PaymentAppManifestProto manifest_proto;
-  bool success = manifest_proto.ParseFromString(input);
-  if (!success)
-    return nullptr;
-
-  payments::mojom::PaymentAppManifestPtr manifest =
-      payments::mojom::PaymentAppManifest::New();
-
-  manifest->label = manifest_proto.label();
-  if (manifest_proto.has_icon())
-    manifest->icon = manifest_proto.icon();
-  for (const auto& option_proto : manifest_proto.options()) {
-    payments::mojom::PaymentAppOptionPtr option =
-        payments::mojom::PaymentAppOption::New();
-    option->label = option_proto.label();
-    if (option_proto.has_icon())
-      option->icon = option_proto.icon();
-    option->id = option_proto.id();
-    for (const auto& method : option_proto.enabled_methods())
-      option->enabled_methods.push_back(method);
-    manifest->options.push_back(std::move(option));
-  }
-
-  return manifest;
-}
-
-bool SerializePaymentAppManifest(
-    payments::mojom::PaymentAppManifestPtr manifest,
-    std::string* output) {
-  DCHECK(manifest);
-
-  PaymentAppManifestProto manifest_proto;
-  manifest_proto.set_label(manifest->label);
-  if (manifest->icon)
-    manifest_proto.set_icon(manifest->icon.value());
-
-  for (const auto& option : manifest->options) {
-    PaymentAppOptionProto* option_proto = manifest_proto.add_options();
-    option_proto->set_label(option->label);
-    if (option->icon)
-      option_proto->set_icon(option->icon.value());
-    option_proto->set_id(option->id);
-    for (const auto& method : option->enabled_methods) {
-      option_proto->add_enabled_methods(method);
-    }
-  }
-
-  return manifest_proto.SerializeToString(output);
-}
-
-}  // namespace
-
-PaymentAppDatabase::PaymentAppDatabase(
-    scoped_refptr<ServiceWorkerContextWrapper> service_worker_context)
-    : service_worker_context_(service_worker_context), weak_ptr_factory_(this) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-}
-
-PaymentAppDatabase::~PaymentAppDatabase() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-}
-
-void PaymentAppDatabase::WriteManifest(
-    const GURL& scope,
-    payments::mojom::PaymentAppManifestPtr manifest,
-    const WriteManifestCallback& callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  service_worker_context_->FindReadyRegistrationForPattern(
-      scope, base::Bind(&PaymentAppDatabase::DidFindRegistrationToWriteManifest,
-                        weak_ptr_factory_.GetWeakPtr(),
-                        base::Passed(std::move(manifest)), callback));
-}
-
-void PaymentAppDatabase::ReadManifest(const GURL& scope,
-                                      const ReadManifestCallback& callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  service_worker_context_->FindReadyRegistrationForPattern(
-      scope, base::Bind(&PaymentAppDatabase::DidFindRegistrationToReadManifest,
-                        weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
-void PaymentAppDatabase::DidFindRegistrationToWriteManifest(
-    payments::mojom::PaymentAppManifestPtr manifest,
-    const WriteManifestCallback& callback,
-    ServiceWorkerStatusCode status,
-    scoped_refptr<ServiceWorkerRegistration> registration) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (status != SERVICE_WORKER_OK) {
-    callback.Run(payments::mojom::PaymentAppManifestError::NO_ACTIVE_WORKER);
-    return;
-  }
-
-  std::string serialized;
-  DCHECK(SerializePaymentAppManifest(std::move(manifest), &serialized));
-
-  service_worker_context_->StoreRegistrationUserData(
-      registration->id(), registration->pattern().GetOrigin(),
-      {{kPaymentAppManifestDataKey, serialized}},
-      base::Bind(&PaymentAppDatabase::DidWriteManifest,
-                 weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
-void PaymentAppDatabase::DidWriteManifest(const WriteManifestCallback& callback,
-                                          ServiceWorkerStatusCode status) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  return callback.Run(status == SERVICE_WORKER_OK
-                          ? payments::mojom::PaymentAppManifestError::NONE
-                          : payments::mojom::PaymentAppManifestError::
-                                MANIFEST_STORAGE_OPERATION_FAILED);
-}
-
-void PaymentAppDatabase::DidFindRegistrationToReadManifest(
-    const ReadManifestCallback& callback,
-    ServiceWorkerStatusCode status,
-    scoped_refptr<ServiceWorkerRegistration> registration) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (status != SERVICE_WORKER_OK) {
-    callback.Run(payments::mojom::PaymentAppManifest::New(),
-                 payments::mojom::PaymentAppManifestError::NO_ACTIVE_WORKER);
-    return;
-  }
-
-  service_worker_context_->GetRegistrationUserData(
-      registration->id(), {kPaymentAppManifestDataKey},
-      base::Bind(&PaymentAppDatabase::DidReadManifest,
-                 weak_ptr_factory_.GetWeakPtr(), callback));
-}
-
-void PaymentAppDatabase::DidReadManifest(const ReadManifestCallback& callback,
-                                         const std::vector<std::string>& data,
-                                         ServiceWorkerStatusCode status) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (status != SERVICE_WORKER_OK || data.size() != 1) {
-    callback.Run(payments::mojom::PaymentAppManifest::New(),
-                 payments::mojom::PaymentAppManifestError::
-                     MANIFEST_STORAGE_OPERATION_FAILED);
-    return;
-  }
-
-  payments::mojom::PaymentAppManifestPtr manifest =
-      DeserializePaymentAppManifest(data[0]);
-  if (!manifest) {
-    callback.Run(payments::mojom::PaymentAppManifest::New(),
-                 payments::mojom::PaymentAppManifestError::
-                     MANIFEST_STORAGE_OPERATION_FAILED);
-    return;
-  }
-
-  callback.Run(std::move(manifest),
-               payments::mojom::PaymentAppManifestError::NONE);
-}
-
-}  // namespace content
diff --git a/content/browser/payments/payment_app_database.h b/content/browser/payments/payment_app_database.h
deleted file mode 100644
index d27b7d838..0000000
--- a/content/browser/payments/payment_app_database.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_DATABASE_H_
-#define CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_DATABASE_H_
-
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "components/payments/payment_app.mojom.h"
-#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
-#include "mojo/public/cpp/bindings/binding.h"
-
-namespace content {
-
-class ServiceWorkerRegistration;
-
-class CONTENT_EXPORT PaymentAppDatabase {
- public:
-  using WriteManifestCallback =
-      base::Callback<void(payments::mojom::PaymentAppManifestError)>;
-  using ReadManifestCallback =
-      base::Callback<void(payments::mojom::PaymentAppManifestPtr,
-                          payments::mojom::PaymentAppManifestError)>;
-
-  explicit PaymentAppDatabase(
-      scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
-  ~PaymentAppDatabase();
-
-  void WriteManifest(const GURL& scope,
-                     payments::mojom::PaymentAppManifestPtr manifest,
-                     const WriteManifestCallback& callback);
-  void ReadManifest(const GURL& scope, const ReadManifestCallback& callback);
-
- private:
-  // WriteManifest callbacks
-  void DidFindRegistrationToWriteManifest(
-      payments::mojom::PaymentAppManifestPtr manifest,
-      const WriteManifestCallback& callback,
-      ServiceWorkerStatusCode status,
-      scoped_refptr<ServiceWorkerRegistration> registration);
-  void DidWriteManifest(const WriteManifestCallback& callback,
-                        ServiceWorkerStatusCode status);
-
-  // ReadManifest callbacks
-  void DidFindRegistrationToReadManifest(
-      const ReadManifestCallback& callback,
-      ServiceWorkerStatusCode status,
-      scoped_refptr<ServiceWorkerRegistration> registration);
-  void DidReadManifest(const ReadManifestCallback& callback,
-                       const std::vector<std::string>& data,
-                       ServiceWorkerStatusCode status);
-
-  scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
-  base::WeakPtrFactory<PaymentAppDatabase> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(PaymentAppDatabase);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_DATABASE_H_
diff --git a/content/browser/payments/payment_app_manager.cc b/content/browser/payments/payment_app_manager.cc
index 52fc1138..bb75263c 100644
--- a/content/browser/payments/payment_app_manager.cc
+++ b/content/browser/payments/payment_app_manager.cc
@@ -9,19 +9,24 @@
 #include "base/bind.h"
 #include "base/optional.h"
 #include "content/browser/payments/payment_app.pb.h"
-#include "content/browser/payments/payment_app_context_impl.h"
+#include "content/browser/payments/payment_app_context.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/public/browser/browser_thread.h"
 
 namespace content {
+namespace {
+
+const char kPaymentAppManifestDataKey[] = "PaymentAppManifestData";
+
+}  // namespace
 
 PaymentAppManager::~PaymentAppManager() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 }
 
 PaymentAppManager::PaymentAppManager(
-    PaymentAppContextImpl* payment_app_context,
+    PaymentAppContext* payment_app_context,
     mojo::InterfaceRequest<payments::mojom::PaymentAppManager> request)
     : payment_app_context_(payment_app_context),
       binding_(this, std::move(request)),
@@ -34,6 +39,10 @@
                  base::Unretained(this)));
 }
 
+void PaymentAppManager::OnConnectionError() {
+  payment_app_context_->ServiceHadConnectionError(this);
+}
+
 void PaymentAppManager::SetManifest(
     const std::string& scope,
     payments::mojom::PaymentAppManifestPtr manifest,
@@ -43,20 +52,128 @@
   // TODO(zino): Should implement requesting a permission for users to allow
   // the payment app to be registered. Please see http://crbug.com/665949.
 
-  payment_app_context_->payment_app_database()->WriteManifest(
-      GURL(scope), std::move(manifest), callback);
+  payment_app_context_->service_worker_context()
+      ->FindReadyRegistrationForPattern(
+          GURL(scope),
+          base::Bind(&PaymentAppManager::DidFindRegistrationToSetManifest,
+                     weak_ptr_factory_.GetWeakPtr(),
+                     base::Passed(std::move(manifest)), callback));
 }
 
 void PaymentAppManager::GetManifest(const std::string& scope,
                                     const GetManifestCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  payment_app_context_->payment_app_database()->ReadManifest(GURL(scope),
-                                                             callback);
+  payment_app_context_->service_worker_context()
+      ->FindReadyRegistrationForPattern(
+          GURL(scope),
+          base::Bind(&PaymentAppManager::DidFindRegistrationToGetManifest,
+                     weak_ptr_factory_.GetWeakPtr(), callback));
 }
 
-void PaymentAppManager::OnConnectionError() {
-  payment_app_context_->ServiceHadConnectionError(this);
+void PaymentAppManager::DidFindRegistrationToSetManifest(
+    payments::mojom::PaymentAppManifestPtr manifest,
+    const SetManifestCallback& callback,
+    ServiceWorkerStatusCode status,
+    scoped_refptr<ServiceWorkerRegistration> registration) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (status != SERVICE_WORKER_OK) {
+    callback.Run(payments::mojom::PaymentAppManifestError::NO_ACTIVE_WORKER);
+    return;
+  }
+
+  PaymentAppManifestProto manifest_proto;
+  manifest_proto.set_label(manifest->label);
+  if (manifest->icon)
+    manifest_proto.set_icon(manifest->icon.value());
+
+  for (const auto& option : manifest->options) {
+    PaymentAppOptionProto* option_proto = manifest_proto.add_options();
+    option_proto->set_label(option->label);
+    if (option->icon)
+      option_proto->set_icon(option->icon.value());
+    option_proto->set_id(option->id);
+    for (const auto& method : option->enabled_methods) {
+      option_proto->add_enabled_methods(method);
+    }
+  }
+
+  std::string serialized;
+  bool success = manifest_proto.SerializeToString(&serialized);
+  DCHECK(success);
+
+  payment_app_context_->service_worker_context()->StoreRegistrationUserData(
+      registration->id(), registration->pattern().GetOrigin(),
+      {{kPaymentAppManifestDataKey, serialized}},
+      base::Bind(&PaymentAppManager::DidSetManifest,
+                 weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
+void PaymentAppManager::DidSetManifest(const SetManifestCallback& callback,
+                                       ServiceWorkerStatusCode status) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  return callback.Run(status == SERVICE_WORKER_OK
+                          ? payments::mojom::PaymentAppManifestError::NONE
+                          : payments::mojom::PaymentAppManifestError::
+                                MANIFEST_STORAGE_OPERATION_FAILED);
+}
+
+void PaymentAppManager::DidFindRegistrationToGetManifest(
+    const GetManifestCallback& callback,
+    ServiceWorkerStatusCode status,
+    scoped_refptr<ServiceWorkerRegistration> registration) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (status != SERVICE_WORKER_OK) {
+    callback.Run(payments::mojom::PaymentAppManifest::New(),
+                 payments::mojom::PaymentAppManifestError::NO_ACTIVE_WORKER);
+    return;
+  }
+
+  payment_app_context_->service_worker_context()->GetRegistrationUserData(
+      registration->id(), {kPaymentAppManifestDataKey},
+      base::Bind(&PaymentAppManager::DidGetManifest,
+                 weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
+void PaymentAppManager::DidGetManifest(const GetManifestCallback& callback,
+                                       const std::vector<std::string>& data,
+                                       ServiceWorkerStatusCode status) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (status != SERVICE_WORKER_OK || data.size() != 1) {
+    callback.Run(payments::mojom::PaymentAppManifest::New(),
+                 payments::mojom::PaymentAppManifestError::
+                     MANIFEST_STORAGE_OPERATION_FAILED);
+    return;
+  }
+
+  PaymentAppManifestProto manifest_proto;
+  bool success = manifest_proto.ParseFromString(data[0]);
+  if (!success) {
+    callback.Run(payments::mojom::PaymentAppManifest::New(),
+                 payments::mojom::PaymentAppManifestError::
+                     MANIFEST_STORAGE_OPERATION_FAILED);
+    return;
+  }
+
+  payments::mojom::PaymentAppManifestPtr manifest =
+      payments::mojom::PaymentAppManifest::New();
+  manifest->label = manifest_proto.label();
+  if (manifest_proto.has_icon())
+    manifest->icon = manifest_proto.icon();
+  for (const auto& option_proto : manifest_proto.options()) {
+    payments::mojom::PaymentAppOptionPtr option =
+        payments::mojom::PaymentAppOption::New();
+    option->label = option_proto.label();
+    if (option_proto.has_icon())
+      option->icon = option_proto.icon();
+    option->id = option_proto.id();
+    for (const auto& method : option_proto.enabled_methods())
+      option->enabled_methods.push_back(method);
+    manifest->options.push_back(std::move(option));
+  }
+
+  callback.Run(std::move(manifest),
+               payments::mojom::PaymentAppManifestError::NONE);
 }
 
 }  // namespace content
diff --git a/content/browser/payments/payment_app_manager.h b/content/browser/payments/payment_app_manager.h
index 12287ab..28d2e85 100644
--- a/content/browser/payments/payment_app_manager.h
+++ b/content/browser/payments/payment_app_manager.h
@@ -11,17 +11,19 @@
 #include "base/memory/weak_ptr.h"
 #include "components/payments/payment_app.mojom.h"
 #include "content/common/content_export.h"
+#include "content/common/service_worker/service_worker_status_code.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
 namespace content {
 
-class PaymentAppContextImpl;
+class PaymentAppContext;
+class ServiceWorkerRegistration;
 
 class CONTENT_EXPORT PaymentAppManager
     : public NON_EXPORTED_BASE(payments::mojom::PaymentAppManager) {
  public:
   PaymentAppManager(
-      PaymentAppContextImpl* payment_app_context,
+      PaymentAppContext* payment_app_context,
       mojo::InterfaceRequest<payments::mojom::PaymentAppManager> request);
 
   ~PaymentAppManager() override;
@@ -36,11 +38,29 @@
   void GetManifest(const std::string& scope,
                    const GetManifestCallback& callback) override;
 
+  // SetManifest callbacks
+  void DidFindRegistrationToSetManifest(
+      payments::mojom::PaymentAppManifestPtr manifest,
+      const SetManifestCallback& callback,
+      ServiceWorkerStatusCode status,
+      scoped_refptr<ServiceWorkerRegistration> registration);
+  void DidSetManifest(const SetManifestCallback& callback,
+                      ServiceWorkerStatusCode status);
+
+  // GetManifest callbacks
+  void DidFindRegistrationToGetManifest(
+      const GetManifestCallback& callback,
+      ServiceWorkerStatusCode status,
+      scoped_refptr<ServiceWorkerRegistration> registration);
+  void DidGetManifest(const GetManifestCallback& callback,
+                      const std::vector<std::string>& data,
+                      ServiceWorkerStatusCode status);
+
   // Called when an error is detected on binding_.
   void OnConnectionError();
 
-  // PaymentAppContextImpl owns PaymentAppManager
-  PaymentAppContextImpl* payment_app_context_;
+  // PaymentAppContext owns PaymentAppManager
+  PaymentAppContext* payment_app_context_;
 
   mojo::Binding<payments::mojom::PaymentAppManager> binding_;
 
diff --git a/content/browser/payments/payment_app_manager_unittest.cc b/content/browser/payments/payment_app_manager_unittest.cc
index 6f03f02e..d29d395 100644
--- a/content/browser/payments/payment_app_manager_unittest.cc
+++ b/content/browser/payments/payment_app_manager_unittest.cc
@@ -62,11 +62,12 @@
             embedded_worker_helper_->browser_context(), base::FilePath(),
             nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
             nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) {
+
     embedded_worker_helper_->context_wrapper()->set_storage_partition(
         storage_partition_impl_.get());
 
-    payment_app_context_ = new PaymentAppContextImpl();
-    payment_app_context_->Init(embedded_worker_helper_->context_wrapper());
+    payment_app_context_ =
+        new PaymentAppContext(embedded_worker_helper_->context_wrapper());
 
     bool called = false;
     embedded_worker_helper_->context()->RegisterServiceWorker(
@@ -108,7 +109,7 @@
   std::unique_ptr<EmbeddedWorkerTestHelper> embedded_worker_helper_;
   std::unique_ptr<StoragePartitionImpl> storage_partition_impl_;
   int64_t sw_registration_id_;
-  scoped_refptr<PaymentAppContextImpl> payment_app_context_;
+  scoped_refptr<PaymentAppContext> payment_app_context_;
   payments::mojom::PaymentAppManagerPtr service_;
 
   // Owned by payment_app_context_.
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 134018fa..12fd4ea 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1209,7 +1209,7 @@
 
   AddUIThreadInterface(
       registry.get(),
-      base::Bind(&PaymentAppContextImpl::CreateService,
+      base::Bind(&PaymentAppContext::CreateService,
                  base::Unretained(
                      storage_partition_impl_->GetPaymentAppContext())));
 
diff --git a/content/browser/resources/media/dump_creator.js b/content/browser/resources/media/dump_creator.js
index 29f053f..90de1d5d 100644
--- a/content/browser/resources/media/dump_creator.js
+++ b/content/browser/resources/media/dump_creator.js
@@ -118,6 +118,7 @@
       {
         'getUserMedia': userMediaRequests,
         'PeerConnections': peerConnectionDataStore,
+        'UserAgent': navigator.userAgent,
       };
       var textBlob = new Blob([JSON.stringify(dump_object, null, ' ')],
                               {type: 'octet/stream'});
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 9e17b4e2..0640453 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -375,7 +375,7 @@
     HostZoomLevelContext* host_zoom_level_context,
     PlatformNotificationContextImpl* platform_notification_context,
     BackgroundSyncContext* background_sync_context,
-    PaymentAppContextImpl* payment_app_context,
+    PaymentAppContext* payment_app_context,
     scoped_refptr<BroadcastChannelProvider> broadcast_channel_provider)
     : partition_path_(partition_path),
       quota_manager_(quota_manager),
@@ -515,9 +515,8 @@
       new BackgroundSyncContext();
   background_sync_context->Init(service_worker_context);
 
-  scoped_refptr<PaymentAppContextImpl> payment_app_context =
-      new PaymentAppContextImpl();
-  payment_app_context->Init(service_worker_context);
+  scoped_refptr<PaymentAppContext> payment_app_context =
+      new PaymentAppContext(service_worker_context);
 
   scoped_refptr<BroadcastChannelProvider>
       broadcast_channel_provider = new BroadcastChannelProvider();
@@ -606,7 +605,7 @@
   return background_sync_context_.get();
 }
 
-PaymentAppContextImpl* StoragePartitionImpl::GetPaymentAppContext() {
+PaymentAppContext* StoragePartitionImpl::GetPaymentAppContext() {
   return payment_app_context_.get();
 }
 
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index f00d02f..b10f3ab 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -22,7 +22,7 @@
 #include "content/browser/host_zoom_level_context.h"
 #include "content/browser/indexed_db/indexed_db_context_impl.h"
 #include "content/browser/notifications/platform_notification_context_impl.h"
-#include "content/browser/payments/payment_app_context_impl.h"
+#include "content/browser/payments/payment_app_context.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/common/content_export.h"
 #include "content/common/storage_partition_service.mojom.h"
@@ -75,7 +75,7 @@
   PlatformNotificationContextImpl* GetPlatformNotificationContext() override;
 
   BackgroundSyncContext* GetBackgroundSyncContext();
-  PaymentAppContextImpl* GetPaymentAppContext();
+  PaymentAppContext* GetPaymentAppContext();
   BroadcastChannelProvider* GetBroadcastChannelProvider();
 
   // mojom::StoragePartitionService interface.
@@ -180,7 +180,7 @@
       HostZoomLevelContext* host_zoom_level_context,
       PlatformNotificationContextImpl* platform_notification_context,
       BackgroundSyncContext* background_sync_context,
-      PaymentAppContextImpl* payment_app_context,
+      PaymentAppContext* payment_app_context,
       scoped_refptr<BroadcastChannelProvider>broadcast_channel_provider);
 
   // We will never have both remove_origin be populated and a cookie_matcher.
@@ -226,7 +226,7 @@
   scoped_refptr<HostZoomLevelContext> host_zoom_level_context_;
   scoped_refptr<PlatformNotificationContextImpl> platform_notification_context_;
   scoped_refptr<BackgroundSyncContext> background_sync_context_;
-  scoped_refptr<PaymentAppContextImpl> payment_app_context_;
+  scoped_refptr<PaymentAppContext> payment_app_context_;
   scoped_refptr<BroadcastChannelProvider> broadcast_channel_provider_;
 
   mojo::BindingSet<mojom::StoragePartitionService> bindings_;
diff --git a/content/public/browser/payment_app_context.h b/content/public/browser/payment_app_context.h
deleted file mode 100644
index 5b464bd..0000000
--- a/content/public/browser/payment_app_context.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_BROWSER_PAYMENT_APP_CONTEXT_H_
-#define CONTENT_PUBLIC_BROWSER_PAYMENT_APP_CONTEXT_H_
-
-#include <utility>
-#include <vector>
-
-#include "base/callback_forward.h"
-
-namespace content {
-
-class PaymentAppContext {
- public:
-  // The ManifestWithID is a pair of the service worker registration id and
-  // the payment app manifest data associated with it.
-  using ManifestWithID =
-      std::pair<int64_t, payments::mojom::PaymentAppManifestPtr>;
-  using Manifests = std::vector<ManifestWithID>;
-  using GetAllManifestsCallback = base::Callback<void(Manifests)>;
-
-  virtual void GetAllManifests(const GetAllManifestsCallback& callback) = 0;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_BROWSER_PAYMENT_APP_CONTEXT_H_
diff --git a/content/public/browser/screen_orientation_provider.cc b/content/public/browser/screen_orientation_provider.cc
index e80c862..bb7cf8d 100644
--- a/content/public/browser/screen_orientation_provider.cc
+++ b/content/public/browser/screen_orientation_provider.cc
@@ -28,10 +28,9 @@
 void ScreenOrientationProvider::LockOrientation(
     blink::WebScreenOrientationLockType orientation,
     const LockOrientationCallback& callback) {
-  // ScreenOrientation should have cancelled all pending request at thie point.
+  // ScreenOrientation should have cancelled all pending request at this point.
   DCHECK(on_result_callback_.is_null());
-  DCHECK(pending_lock_orientation_.has_value());
-  DCHECK(pending_lock_orientation_.value() >= 0);
+  DCHECK(!pending_lock_orientation_.has_value());
   on_result_callback_ = callback;
 
   if (!delegate_ || !delegate_->ScreenOrientationProviderSupported()) {
diff --git a/content/renderer/media/peer_connection_tracker.cc b/content/renderer/media/peer_connection_tracker.cc
index 3e2dc70..ef1d234 100644
--- a/content/renderer/media/peer_connection_tracker.cc
+++ b/content/renderer/media/peer_connection_tracker.cc
@@ -90,8 +90,8 @@
 
 static std::string SerializeMediaDescriptor(
     const blink::WebMediaStream& stream) {
-  std::string label = base::UTF16ToUTF8(base::StringPiece16(stream.id()));
-  std::string result = "label: " + label;
+  std::string id = base::UTF16ToUTF8(base::StringPiece16(stream.id()));
+  std::string result = "id: " + id;
   blink::WebVector<blink::WebMediaStreamTrack> tracks;
   stream.audioTracks(tracks);
   if (!tracks.isEmpty()) {
diff --git a/device/power_monitor/public/cpp/BUILD.gn b/device/power_monitor/public/cpp/BUILD.gn
index 3303541..d586540 100644
--- a/device/power_monitor/public/cpp/BUILD.gn
+++ b/device/power_monitor/public/cpp/BUILD.gn
@@ -6,13 +6,10 @@
 
 source_set("cpp") {
   sources = [
-    "//device/power_monitor/power_monitor_export.h",
     "power_monitor_broadcast_source.cc",
     "power_monitor_broadcast_source.h",
   ]
 
-  defines = [ "DEVICE_POWER_MONITOR_IMPLEMENTATION" ]
-
   deps = [
     "//base",
     "//mojo/public/cpp/bindings",
diff --git a/device/power_monitor/public/cpp/power_monitor_broadcast_source.h b/device/power_monitor/public/cpp/power_monitor_broadcast_source.h
index 596d07b..2a4c94a0 100644
--- a/device/power_monitor/public/cpp/power_monitor_broadcast_source.h
+++ b/device/power_monitor/public/cpp/power_monitor_broadcast_source.h
@@ -7,7 +7,6 @@
 
 #include "base/macros.h"
 #include "base/power_monitor/power_monitor_source.h"
-#include "device/power_monitor/power_monitor_export.h"
 #include "device/power_monitor/public/interfaces/power_monitor.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
@@ -16,9 +15,8 @@
 
 // Receives state changes from Power Monitor through mojo, and relays them to
 // the PowerMonitor of the current process.
-class DEVICE_POWER_MONITOR_EXPORT PowerMonitorBroadcastSource
-    : public base::PowerMonitorSource,
-      NON_EXPORTED_BASE(public device::mojom::PowerMonitorClient) {
+class PowerMonitorBroadcastSource : public base::PowerMonitorSource,
+                                    public device::mojom::PowerMonitorClient {
  public:
   explicit PowerMonitorBroadcastSource(
       service_manager::InterfaceProvider* interface_provider);
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index 11d23191..e5b8f4fa 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/buildflag_header.gni")
 import("//build/config/features.gni")
 import("//build/config/ios/rules.gni")
 import("//third_party/protobuf/proto_library.gni")
@@ -21,6 +22,8 @@
 
 source_set("browser") {
   sources = [
+    "about_flags.h",
+    "about_flags.mm",
     "app_startup_parameters.h",
     "app_startup_parameters.mm",
     "application_context.cc",
@@ -74,10 +77,14 @@
     "xcallback_parameters.mm",
   ]
   deps = [
+    ":google_api_keys_header",
     ":settings_resources",
     "//base",
     "//components/autofill/core/browser",
     "//components/autofill/core/common",
+    "//components/dom_distiller/core",
+    "//components/flags_ui",
+    "//components/flags_ui:switches",
     "//components/gcm_driver",
     "//components/handoff",
     "//components/keyed_service/core",
@@ -95,12 +102,16 @@
     "//components/search_engines",
     "//components/signin/core/browser",
     "//components/ssl_config",
+    "//components/strings",
+    "//components/sync",
     "//components/translate/core/browser",
     "//components/url_formatter",
     "//components/variations",
     "//components/variations/service",
     "//components/version_info",
     "//components/webdata_services",
+    "//google_apis",
+    "//ios/chrome/app/strings",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/sync/glue",
     "//ios/chrome/common",
@@ -128,7 +139,6 @@
     "ios_chrome_main_parts.mm",
   ]
   deps = [
-    ":about_flags",
     ":browser",
     "//base",
     "//components/component_updater",
@@ -180,35 +190,9 @@
   }
 }
 
-# This is a separate target so that the 'defines' does not leak to the
-# other files (which would increase the compilation time when changing
-# the value).
-source_set("about_flags") {
-  configs += [ "//build/config/compiler:enable_arc" ]
-  sources = [
-    "about_flags.h",
-    "about_flags.mm",
-  ]
-
-  deps = [
-    ":browser",
-    "//base",
-    "//components/autofill/core/common",
-    "//components/dom_distiller/core",
-    "//components/flags_ui",
-    "//components/flags_ui:switches",
-    "//components/ntp_tiles",
-    "//components/reading_list/core",
-    "//components/strings",
-    "//components/sync",
-    "//components/variations",
-    "//google_apis",
-    "//ios/chrome/app/strings",
-    "//ios/web",
-    "//ios/web:user_agent",
-  ]
-
-  defines = [
+buildflag_header("google_api_keys_header") {
+  header = "google_api_keys.h"
+  flags = [
     "GOOGLE_STAGING_API_URL=\"$google_staging_api_url\"",
     "GOOGLE_STAGING_LSO_URL=\"$google_staging_lso_url\"",
     "GOOGLE_TEST_API_URL=\"$google_test_api_url\"",
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index eb01c74f..4fbfd94f 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -31,6 +31,7 @@
 #include "components/sync/driver/sync_driver_switches.h"
 #include "google_apis/gaia/gaia_switches.h"
 #include "ios/chrome/browser/chrome_switches.h"
+#include "ios/chrome/browser/google_api_keys.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ios/web/public/user_agent.h"
 #include "ios/web/public/web_view_creation_util.h"
@@ -39,10 +40,6 @@
 #include "components/variations/variations_switches.h"
 #endif
 
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
 namespace {
 // To add a new entry, add to the end of kFeatureEntries. There are two
 // distinct types of entries:
@@ -79,19 +76,22 @@
   NSString* gaia_environment = [defaults stringForKey:kGAIAEnvironment];
   if ([gaia_environment isEqualToString:@"Staging"]) {
     command_line->AppendSwitchASCII(switches::kGoogleApisUrl,
-                                    GOOGLE_STAGING_API_URL);
-    command_line->AppendSwitchASCII(switches::kLsoUrl, GOOGLE_STAGING_LSO_URL);
+                                    BUILDFLAG(GOOGLE_STAGING_API_URL));
+    command_line->AppendSwitchASCII(switches::kLsoUrl,
+                                    BUILDFLAG(GOOGLE_STAGING_LSO_URL));
   } else if ([gaia_environment isEqualToString:@"Test"]) {
-    command_line->AppendSwitchASCII(switches::kGaiaUrl, GOOGLE_TEST_OAUTH_URL);
+    command_line->AppendSwitchASCII(switches::kGaiaUrl,
+                                    BUILDFLAG(GOOGLE_TEST_OAUTH_URL));
     command_line->AppendSwitchASCII(switches::kGoogleApisUrl,
-                                    GOOGLE_TEST_API_URL);
-    command_line->AppendSwitchASCII(switches::kLsoUrl, GOOGLE_TEST_LSO_URL);
+                                    BUILDFLAG(GOOGLE_TEST_API_URL));
+    command_line->AppendSwitchASCII(switches::kLsoUrl,
+                                    BUILDFLAG(GOOGLE_TEST_LSO_URL));
     command_line->AppendSwitchASCII(switches::kSyncServiceURL,
-                                    GOOGLE_TEST_SYNC_URL);
+                                    BUILDFLAG(GOOGLE_TEST_SYNC_URL));
     command_line->AppendSwitchASCII(switches::kOAuth2ClientID,
-                                    GOOGLE_TEST_OAUTH_CLIENT_ID);
+                                    BUILDFLAG(GOOGLE_TEST_OAUTH_CLIENT_ID));
     command_line->AppendSwitchASCII(switches::kOAuth2ClientSecret,
-                                    GOOGLE_TEST_OAUTH_CLIENT_SECRET);
+                                    BUILDFLAG(GOOGLE_TEST_OAUTH_CLIENT_SECRET));
   }
 
   // Populate command line flag for the Tab Switcher experiment from the
diff --git a/ios/chrome/browser/ui/webui/BUILD.gn b/ios/chrome/browser/ui/webui/BUILD.gn
index eae50c3..dc98999c 100644
--- a/ios/chrome/browser/ui/webui/BUILD.gn
+++ b/ios/chrome/browser/ui/webui/BUILD.gn
@@ -38,7 +38,6 @@
     "//google_apis",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser",
-    "//ios/chrome/browser:about_flags",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/crash_report",
     "//ios/chrome/browser/metrics",
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index 20c1e516..51a57d7 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -113,7 +113,6 @@
 webkit.org/b/90488 [ Debug ] http/tests/inspector-enabled/ [ Slow ]
 webkit.org/b/90488 [ Debug ] virtual/mojo-loading/http/tests/inspector-enabled/ [ Slow ]
 webkit.org/b/90488 [ Debug ] inspector-protocol/ [ Slow ]
-crbug.com/673296 [ Android ] inspector-protocol/input/dispatchMouseEvent.html [ Slow ]
 crbug.com/451577 inspector/console [ Slow ]
 crbug.com/451577 [ Win ] http/tests/inspector/network/network-datareceived.html [ Slow ]
 crbug.com/451577 [ Win ] virtual/mojo-loading/http/tests/inspector/network/network-datareceived.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 5b83f0e..66b2f82 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -706,6 +706,7 @@
 crbug.com/518988 [ Win7 ] http/tests/xmlhttprequest/xmlhttprequest-50ms-download-dispatch.html [ Failure Pass ]
 crbug.com/518989 [ Mac ] imported/csswg-test/css-writing-modes-3/writing-mode-vertical-rl-002.xht [ Failure Pass Timeout ]
 crbug.com/518998 media/video-poster-after-loadedmetadata.html [ Failure Pass ]
+crbug.com/673296 [ Android ] inspector-protocol/input/dispatchMouseEvent.html [ Pass Timeout ]
 
 # These performance-sensitive user-timing tests are flaky in debug on all platforms, and flaky on all configurations of windows.
 # See: crbug.com/567965, crbug.com/518992, and crbug.com/518993
@@ -1360,7 +1361,8 @@
 crbug.com/654999 [ Win Linux ] fast/forms/color/color-suggestion-picker-appearance-zoom200.html [ Pass Failure ]
 crbug.com/660185 [ Mac ] fast/forms/datalist/input-appearance-range-with-transform.html [ Pass Failure ]
 
-crbug.com/658304 [ Win Linux ] fast/forms/select/input-select-after-resize.html [ Crash Timeout Pass ]
+# TODO(tkent): Re-enable after rebaseline for crbug.com/667236
+# crbug.com/658304 [ Win Linux ] fast/forms/select/input-select-after-resize.html [ Crash Timeout Pass ]
 
 crbug.com/659192 virtual/gpu/fast/canvas/canvas-imageSmoothingQuality-pixel.html [ NeedsManualRebaseline ]
 
@@ -1889,7 +1891,108 @@
 
 crbug.com/657968 storage/indexeddb/idbdatabase-createObjectStore-exception-order.html [ Pass Failure ]
 crbug.com/657968 storage/indexeddb/idbdatabase-deleteObjectStore-exception-order.html [ Pass Failure ]
-
+crbug.com/667236 fast/forms/select/menulist-appearance-basic.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux ] fast/forms/select/basic-selects.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux ] fast/forms/select/select-autofilled.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] css3/selectors3/html/css3-modsel-161.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] css3/selectors3/xhtml/css3-modsel-161.xml [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] css3/selectors3/xml/css3-modsel-161.xml [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] editing/selection/replaced-boundaries-3.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] editing/selection/select-box.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] editing/selection/select-element-paragraph-boundary.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/block/float/float-avoidance.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/block/margin-collapse/103.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/001.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/color/color-suggestion-picker-appearance-zoom125.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/color/color-suggestion-picker-appearance.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/color/color-suggestion-picker-one-row-appearance.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/color/color-suggestion-picker-two-row-appearance.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/color/input-appearance-color.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/control-clip-overflow.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/control-restrict-line-height.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/form-element-geometry.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-empty.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-long.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-many.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-minimum-font.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-rtl-default.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-single-option.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-styled.html [ NeedsRebaseline ]
+crbug.com/667236 [ Win ] fast/forms/select-popup/popup-menu-appearance-tall.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-texttransform.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-transform.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-zoom.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance-zoom090.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select-popup/popup-menu-appearance.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/003.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/004.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/HTMLOptionElement_label01.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/HTMLOptionElement_label02.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/HTMLOptionElement_label03.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/HTMLOptionElement_label04.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/HTMLOptionElement_label06.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/HTMLOptionElement_label07.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/disabled-select-change-index.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/input-select-after-resize.html [ NeedsManualRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/menulist-appearance-rtl.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/menulist-deselect-update.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/menulist-narrow-width.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/menulist-no-overflow.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/menulist-restrict-line-height.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/menulist-separator-painting.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/menulist-style-color.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/menulist-update-text-popup.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/menulist-width-change.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/optgroup-rendering.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/option-script.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/option-strip-whitespace.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/option-text-clip.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-align.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-background-none.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-baseline.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-change-listbox-to-popup.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-dirty-parent-pref-widths.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-disabled-appearance.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-initial-position.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-selected.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-size-invalid.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-style.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-visual-hebrew.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/select-writing-direction-natural.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/select/selectlist-minsize.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/forms/stuff-on-my-optgroup.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/html/keygen.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/invalid/014.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/parser/document-write-option.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/replaced/replaced-breaking-mixture.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/replaced/replaced-breaking.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/replaced/three-selects-break.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] fast/replaced/width100percent-menulist.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] http/tests/webfont/popup-menu-load-webfont-after-open.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla/bugs/bug1188.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla/bugs/bug18359.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla/bugs/bug2479-3.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla/bugs/bug2479-4.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla/bugs/bug29326.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla/bugs/bug33855.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla/bugs/bug4382.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla/bugs/bug96334.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla/core/margins.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla/dom/tableDom.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] tables/mozilla_expected_failures/bugs/bug2479-5.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] transforms/2d/zoom-menulist.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] virtual/mojo-loading/http/tests/webfont/popup-menu-load-webfont-after-open.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] virtual/parsehtmlonmainthread_coalesce/fast/parser/document-write-option.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] virtual/parsehtmlonmainthread_sync/fast/parser/document-write-option.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] virtual/scalefactor150/fast/hidpi/static/popup-menu-appearance.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance.html [ NeedsRebaseline ]
+crbug.com/667236 [ Linux Win ] virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance.html [ NeedsRebaseline ]
+crbug.com/667236 accessibility/disabled-controls-not-focusable.html [ NeedsRebaseline ]
+crbug.com/667236 fast/canvas/fallback-content.html [ NeedsRebaseline ]
+crbug.com/667236 virtual/display_list_2d_canvas/fast/canvas/fallback-content.html [ NeedsRebaseline ]
+crbug.com/667236 virtual/gpu/fast/canvas/fallback-content.html [ NeedsRebaseline ]
 crbug.com/659610 fast/css-grid-layout/grid-baseline.html [ Failure ]
 crbug.com/659610 fast/css-grid-layout/grid-baseline-margins.html [ Failure ]
 
diff --git a/third_party/WebKit/LayoutTests/accessibility/disabled-controls-not-focusable.html b/third_party/WebKit/LayoutTests/accessibility/disabled-controls-not-focusable.html
index 39d5e98..e26526a 100644
--- a/third_party/WebKit/LayoutTests/accessibility/disabled-controls-not-focusable.html
+++ b/third_party/WebKit/LayoutTests/accessibility/disabled-controls-not-focusable.html
@@ -3,7 +3,7 @@
 <body>
 <script src="../resources/js-test.js"></script>
 
-<div>
+<div id="container">
   <button id="button"></button>
   <input id="text" type="text">
   <input id="checkbox" type="checkbox">
@@ -41,6 +41,8 @@
     checkControl("combobox");
     checkControl("listbox");
     checkControl("textarea");
+
+    document.querySelector("#container").remove();
 }
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/fallback-content.html b/third_party/WebKit/LayoutTests/fast/canvas/fallback-content.html
index c3c69f41..699aecb 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/fallback-content.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/fallback-content.html
@@ -2,7 +2,7 @@
 <html>
 <body>
 <script src="../../resources/js-test.js"></script>
-
+<div id="container">
 <div>
   <a id="link1" href="#">Link</a>
   <button id="button1">Button</button>
@@ -34,7 +34,7 @@
 <canvas hidden id="hiddenCanvas" width="300" height="300">
   <a id="linkInHiddenCanvas" href="#">Link</a>
 </canvas>
-
+</div>
 <div id="console"></div>
 <script>
 description("This test makes sure that focusable elements in canvas fallback content are focusable.");
@@ -87,6 +87,7 @@
 
 checkNotFocusable("linkInHiddenCanvas");
 
+document.querySelector("#container").remove();
 </script>
 
 </body>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-radio-img-node-list-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/form-radio-img-node-list-expected.txt
index baf968c..960ec29 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-radio-img-node-list-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-radio-img-node-list-expected.txt
@@ -19,5 +19,3 @@
 
 TEST COMPLETE
 
-                    
-
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-radio-img-node-list.html b/third_party/WebKit/LayoutTests/fast/forms/form-radio-img-node-list.html
index 1f4d628..616aff84 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-radio-img-node-list.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-radio-img-node-list.html
@@ -1,5 +1,6 @@
 <!doctype html>
 <script src="../../resources/js-test.js"></script>
+<div id="container">
 <img name=outside1></img>
 <form id="f1">
     <button id=n1></button>
@@ -17,6 +18,7 @@
 </form>
 <!-- The img element isn't 'reassociatable'; add @form to verify it is so. -->
 <img name=n2 form=f1></img>
+</div>
 <script>
 description("Test RadioNodeLists returned by the HTMLFormElement named-getter.");
 
@@ -47,4 +49,6 @@
 img.name = "n2";
 form.appendChild(img);
 verifyLength(3);
+
+document.querySelector("#container").remove();
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/select/menulist-appearance-basic.html b/third_party/WebKit/LayoutTests/fast/forms/select/menulist-appearance-basic.html
index 4023695b..621cd0c 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/select/menulist-appearance-basic.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/select/menulist-appearance-basic.html
@@ -51,7 +51,9 @@
 
 <!-- zoom -->
 <select style="zoom: 1.5;"><option>foo</option></select>
-<select style="zoom: 2;"><option>foo</option></select> <br>
+<select style="zoom: 2;"><option>foo</option></select>
+<select style="zoom: 0.5;"><option>foo</option></select>
+<br>
 
 <!-- multiple - on platforms that use menulist rendering for <select multiple> tags -->
 <select multiple="multiple" style="width: 200px; height: 25px;">
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-radio-img-node-list-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-radio-img-node-list-expected.txt
deleted file mode 100644
index baf968c..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/form-radio-img-node-list-expected.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-CONSOLE WARNING: The <keygen> element is deprecated and will be removed in M57, around March 2017. See https://www.chromestatus.com/features/5716060992962560 for more details.
-Test RadioNodeLists returned by the HTMLFormElement named-getter.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-Check that if no 'listed elements' match by name, img elements are picked instead.
-PASS radioNodeList.length is 2
-PASS radioNodeList[0] instanceof HTMLImageElement is true
-PASS radioNodeList[1] instanceof HTMLImageElement is true
-PASS radioNodeList.length is 2
-PASS radioNodeList[0] instanceof HTMLImageElement is true
-PASS radioNodeList[1] instanceof HTMLImageElement is true
-PASS radioNodeList.length is 3
-PASS radioNodeList[0] instanceof HTMLImageElement is true
-PASS radioNodeList[1] instanceof HTMLImageElement is true
-PASS radioNodeList[2] instanceof HTMLImageElement is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-                    
-
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-radio-img-node-list-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-radio-img-node-list-expected.txt
deleted file mode 100644
index 73a5544..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/form-radio-img-node-list-expected.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-CONSOLE WARNING: The <keygen> element is deprecated and will be removed in M57, around March 2017. See https://www.chromestatus.com/features/5716060992962560 for more details.
-Test RadioNodeLists returned by the HTMLFormElement named-getter.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-Check that if no 'listed elements' match by name, img elements are picked instead.
-PASS radioNodeList.length is 2
-PASS radioNodeList[0] instanceof HTMLImageElement is true
-PASS radioNodeList[1] instanceof HTMLImageElement is true
-PASS radioNodeList.length is 2
-PASS radioNodeList[0] instanceof HTMLImageElement is true
-PASS radioNodeList[1] instanceof HTMLImageElement is true
-PASS radioNodeList.length is 3
-PASS radioNodeList[0] instanceof HTMLImageElement is true
-PASS radioNodeList[1] instanceof HTMLImageElement is true
-PASS radioNodeList[2] instanceof HTMLImageElement is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-                   
-
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png
index 3d984a3..28bac72 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.txt
index 8208717..747b6455 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.txt
@@ -106,7 +106,13 @@
             text run at (8,2) width 38: "foo"
       LayoutText {#text} at (181,235) size 4x17
         text run at (181,235) width 4: " "
-      LayoutBR {BR} at (185,235) size 0x17
+      LayoutMenuList {SELECT} at (187,239) size 35x14 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+        LayoutBlockFlow (anonymous) at (1,1) size 33x12
+          LayoutText (anonymous) at (2,0) size 14x12
+            text run at (2,0) width 14: "foo"
+      LayoutText {#text} at (224,235) size 4x17
+        text run at (224,235) width 4: " "
+      LayoutBR {BR} at (228,235) size 0x17
       LayoutText {#text} at (208,283) size 4x17
         text run at (208,283) width 4: " "
       LayoutBR {BR} at (212,283) size 0x17
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-rtl-expected.png
index 113d59b0..8cc4a1dc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-rtl-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-rtl-expected.txt
index 461e372f..9249ac5 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-rtl-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-rtl-expected.txt
@@ -62,8 +62,8 @@
           LayoutText {#text} at (0,0) size 101x16
             text run at (0,0) width 101 RTL: "\x{627}\x{644}\x{627}\x{642}\x{62A}\x{631}\x{627}\x{62D}\x{627}\x{62A} / \x{627}\x{644}\x{634}\x{643}\x{627}\x{648}\x{64A}"
         LayoutBlockFlow (anonymous) at (0,34) size 784x20
-          LayoutMenuList {SELECT} at (0,0) size 115x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
-            LayoutBlockFlow (anonymous) at (1,1) size 113x18
+          LayoutMenuList {SELECT} at (0,0) size 113x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)]
+            LayoutBlockFlow (anonymous) at (1,1) size 111x18
               LayoutText (anonymous) at (4,1) size 82x16
                 text run at (4,1) width 82 RTL: "\x{627}\x{644}\x{627}\x{642}\x{62A}\x{631}\x{627}\x{62D}\x{627}\x{62A} / \x{627}\x{644}\x{634}\x{643}\x{627}\x{648}\x{64A}"
           LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/Source/bindings/core/v8/TraceWrapperMember.h b/third_party/WebKit/Source/bindings/core/v8/TraceWrapperMember.h
index 660f519..eb68310d 100644
--- a/third_party/WebKit/Source/bindings/core/v8/TraceWrapperMember.h
+++ b/third_party/WebKit/Source/bindings/core/v8/TraceWrapperMember.h
@@ -28,7 +28,15 @@
 #if DCHECK_IS_ON()
     DCHECK(!m_parent || HeapObjectHeader::fromPayload(m_parent)->checkHeader());
 #endif
-    ScriptWrappableVisitor::writeBarrier(m_parent, raw);
+    // We don't require a write barrier here as TraceWrapperMember is used for
+    // the following scenarios:
+    // - Initial initialization: The write barrier will not fire as the parent
+    //   is initially white.
+    // - Wrapping when inserting into a container: The write barrier will fire
+    //   upon establishing the move into the container.
+    // - Assignment to a field: The regular assignment operator will fire the
+    //   write barrier.
+    // Note that support for black allocation would require a barrier here.
   }
   TraceWrapperMember(WTF::HashTableDeletedValueType x)
       : Member<T>(x), m_parent(nullptr) {}
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp b/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
index efaf6f2..953afd5 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
+++ b/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
@@ -32,7 +32,7 @@
 #include "core/editing/EphemeralRange.h"
 #include "core/editing/FrameSelection.h"
 #include "core/editing/serializers/Serialization.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fileapi/FileList.h"
 #include "core/frame/LocalFrame.h"
 #include "core/html/HTMLImageElement.h"
@@ -228,7 +228,7 @@
   m_dragImageElement = nullptr;
 }
 
-void DataTransfer::setDragImageResource(ImageResource* img,
+void DataTransfer::setDragImageResource(ImageResourceContent* img,
                                         const IntPoint& loc) {
   setDragImage(img, 0, loc);
 }
@@ -252,8 +252,8 @@
   return nullptr;
 }
 
-static ImageResource* getImageResource(Element* element) {
-  // Attempt to pull ImageResource from element
+static ImageResourceContent* getImageResourceContent(Element* element) {
+  // Attempt to pull ImageResourceContent from element
   ASSERT(element);
   LayoutObject* layoutObject = element->layoutObject();
   if (!layoutObject || !layoutObject->isImage())
@@ -270,7 +270,7 @@
                                    Element* element,
                                    const KURL& url) {
   // Shove image data into a DataObject for use as a file
-  ImageResource* cachedImage = getImageResource(element);
+  ImageResourceContent* cachedImage = getImageResourceContent(element);
   if (!cachedImage || !cachedImage->getImage() || !cachedImage->isLoaded())
     return;
 
@@ -449,7 +449,7 @@
       m_transferType(type),
       m_dataObject(dataObject) {}
 
-void DataTransfer::setDragImage(ImageResource* image,
+void DataTransfer::setDragImage(ImageResourceContent* image,
                                 Node* node,
                                 const IntPoint& loc) {
   if (!canSetDragImage())
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransfer.h b/third_party/WebKit/Source/core/clipboard/DataTransfer.h
index 2c6d3058..13d54a2 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransfer.h
+++ b/third_party/WebKit/Source/core/clipboard/DataTransfer.h
@@ -27,7 +27,7 @@
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "core/CoreExport.h"
 #include "core/clipboard/DataTransferAccessPolicy.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/page/DragActions.h"
 #include "platform/geometry/IntPoint.h"
 #include "platform/heap/Handle.h"
@@ -93,7 +93,7 @@
   IntPoint dragLocation() const { return m_dragLoc; }
   void setDragImage(Element*, int x, int y);
   void clearDragImage();
-  void setDragImageResource(ImageResource*, const IntPoint&);
+  void setDragImageResource(ImageResourceContent*, const IntPoint&);
   void setDragImageElement(Node*, const IntPoint&);
 
   std::unique_ptr<DragImage> createDragImage(IntPoint& dragLocation,
@@ -129,7 +129,7 @@
  private:
   DataTransfer(DataTransferType, DataTransferAccessPolicy, DataObject*);
 
-  void setDragImage(ImageResource*, Node*, const IntPoint&);
+  void setDragImage(ImageResourceContent*, Node*, const IntPoint&);
 
   bool hasFileOfType(const String&) const;
   bool hasStringOfType(const String&) const;
@@ -143,7 +143,7 @@
   Member<DataObject> m_dataObject;
 
   IntPoint m_dragLoc;
-  Member<ImageResource> m_dragImage;
+  Member<ImageResourceContent> m_dragImage;
   Member<Node> m_dragImageElement;
 };
 
diff --git a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
index 7f75fae7..72654f6 100644
--- a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
@@ -59,8 +59,8 @@
   return false;
 }
 
-static ImageResource* cachedImageForCSSValue(CSSValue* value,
-                                             const Document& document) {
+static ImageResourceContent* cachedImageForCSSValue(CSSValue* value,
+                                                    const Document& document) {
   if (!value)
     return nullptr;
 
@@ -87,7 +87,7 @@
 
 static Image* renderableImageForCSSValue(CSSValue* value,
                                          const LayoutObject& layoutObject) {
-  ImageResource* cachedImage =
+  ImageResourceContent* cachedImage =
       cachedImageForCSSValue(value, layoutObject.document());
 
   if (!cachedImage || cachedImage->errorOccurred() ||
@@ -199,8 +199,8 @@
 }
 
 void CSSCrossfadeValue::loadSubimages(const Document& document) {
-  ImageResource* oldCachedFromImage = m_cachedFromImage;
-  ImageResource* oldCachedToImage = m_cachedToImage;
+  ImageResourceContent* oldCachedFromImage = m_cachedFromImage;
+  ImageResourceContent* oldCachedToImage = m_cachedToImage;
 
   m_cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), document);
   m_cachedToImage = cachedImageForCSSValue(m_toValue.get(), document);
@@ -266,7 +266,7 @@
 }
 
 void CSSCrossfadeValue::CrossfadeSubimageObserverProxy::imageChanged(
-    ImageResource*,
+    ImageResourceContent*,
     const IntRect* rect) {
   if (m_ready)
     m_ownerValue->crossfadeChanged(*rect);
diff --git a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h
index 16e5bbb87..ac154b2 100644
--- a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h
+++ b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h
@@ -29,13 +29,12 @@
 #include "core/CoreExport.h"
 #include "core/css/CSSImageGeneratorValue.h"
 #include "core/css/CSSPrimitiveValue.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ImageResourceObserver.h"
 #include "platform/graphics/Image.h"
 
 namespace blink {
 
-class ImageResource;
 class CrossfadeSubimageObserverProxy;
 class LayoutObject;
 
@@ -88,7 +87,7 @@
     ~CrossfadeSubimageObserverProxy() override {}
     DEFINE_INLINE_TRACE() { visitor->trace(m_ownerValue); }
 
-    void imageChanged(ImageResource*, const IntRect* = nullptr) override;
+    void imageChanged(ImageResourceContent*, const IntRect* = nullptr) override;
     bool willRenderImage() override;
     String debugName() const override {
       return "CrossfadeSubimageObserverProxy";
@@ -107,8 +106,8 @@
   Member<CSSValue> m_toValue;
   Member<CSSPrimitiveValue> m_percentageValue;
 
-  Member<ImageResource> m_cachedFromImage;
-  Member<ImageResource> m_cachedToImage;
+  Member<ImageResourceContent> m_cachedFromImage;
+  Member<ImageResourceContent> m_cachedToImage;
 
   CrossfadeSubimageObserverProxy m_crossfadeSubimageObserver;
 };
diff --git a/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp b/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp
index 6e764a9..307fc97 100644
--- a/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp
@@ -23,7 +23,7 @@
 
 #include "core/SVGNames.h"
 #include "core/css/CSSImageSetValue.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/style/StyleFetchedImage.h"
 #include "core/style/StyleFetchedImageSet.h"
 #include "core/style/StyleImage.h"
diff --git a/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp b/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp
index de1297d..c50069c 100644
--- a/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp
@@ -30,7 +30,7 @@
 #include "core/dom/Document.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
 #include "core/fetch/FetchRequest.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ResourceLoaderOptions.h"
 #include "core/frame/Settings.h"
@@ -120,8 +120,8 @@
     if (document.settings() && document.settings()->fetchImagePlaceholders())
       request.setAllowImagePlaceholder();
 
-    if (ImageResource* cachedImage =
-            ImageResource::fetch(request, document.fetcher()))
+    if (ImageResourceContent* cachedImage =
+            ImageResourceContent::fetch(request, document.fetcher()))
       m_cachedImage = StyleFetchedImageSet::create(
           cachedImage, image.scaleFactor, this, request.url());
     else
@@ -165,7 +165,7 @@
 bool CSSImageSetValue::hasFailedOrCanceledSubresources() const {
   if (!m_cachedImage)
     return false;
-  if (Resource* cachedResource = m_cachedImage->cachedImage())
+  if (ImageResourceContent* cachedResource = m_cachedImage->cachedImage())
     return cachedResource->loadFailedOrCanceled();
   return true;
 }
diff --git a/third_party/WebKit/Source/core/css/CSSImageValue.cpp b/third_party/WebKit/Source/core/css/CSSImageValue.cpp
index a0dd40c..727f81c9 100644
--- a/third_party/WebKit/Source/core/css/CSSImageValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSImageValue.cpp
@@ -24,7 +24,7 @@
 #include "core/dom/Document.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
 #include "core/fetch/FetchRequest.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/frame/Settings.h"
 #include "core/style/StyleFetchedImage.h"
@@ -67,8 +67,8 @@
     if (document.settings() && document.settings()->fetchImagePlaceholders())
       request.setAllowImagePlaceholder();
 
-    if (ImageResource* cachedImage =
-            ImageResource::fetch(request, document.fetcher()))
+    if (ImageResourceContent* cachedImage =
+            ImageResourceContent::fetch(request, document.fetcher()))
       m_cachedImage =
           StyleFetchedImage::create(cachedImage, document, request.url());
     else
@@ -83,13 +83,12 @@
   if (!m_cachedImage || !document.fetcher() || m_absoluteURL.isNull())
     return;
 
-  ImageResource* resource = m_cachedImage->cachedImage();
+  ImageResourceContent* resource = m_cachedImage->cachedImage();
   if (!resource)
     return;
 
-  document.fetcher()->emulateLoadStartedForInspector(
-      resource, KURL(ParsedURLString, m_absoluteURL),
-      WebURLRequest::RequestContextImage,
+  resource->emulateLoadStartedForInspector(
+      document.fetcher(), KURL(ParsedURLString, m_absoluteURL),
       m_initiatorName.isEmpty() ? FetchInitiatorTypeNames::css
                                 : m_initiatorName);
 }
@@ -97,7 +96,7 @@
 bool CSSImageValue::hasFailedOrCanceledSubresources() const {
   if (!m_cachedImage)
     return false;
-  if (Resource* cachedResource = m_cachedImage->cachedImage())
+  if (ImageResourceContent* cachedResource = m_cachedImage->cachedImage())
     return cachedResource->loadFailedOrCanceled();
   return true;
 }
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp
index ac8e99b..30d74bf 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp
@@ -53,7 +53,8 @@
   if (isCachePending())
     return nullptr;
   // cachedImage can be null if image is StyleInvalidImage
-  ImageResource* cachedImage = m_imageValue->cachedImage()->cachedImage();
+  ImageResourceContent* cachedImage =
+      m_imageValue->cachedImage()->cachedImage();
   if (cachedImage) {
     // getImage() returns the nullImage() if the image is not available yet
     return cachedImage->getImage()->imageForDefaultFrame();
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h
index 1c6278c0..a380f4f 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h
@@ -10,7 +10,7 @@
 #include "core/css/CSSImageValue.h"
 #include "core/css/cssom/CSSResourceValue.h"
 #include "core/css/cssom/CSSStyleValue.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/html/canvas/CanvasImageSource.h"
 #include "core/imagebitmap/ImageBitmapSource.h"
 #include "core/style/StyleImage.h"
@@ -57,7 +57,7 @@
   virtual LayoutSize imageLayoutSize() const {
     DCHECK(!isCachePending());
     return m_imageValue->cachedImage()->cachedImage()->imageSize(
-        DoNotRespectImageOrientation, 1, ImageResource::IntrinsicSize);
+        DoNotRespectImageOrientation, 1, ImageResourceContent::IntrinsicSize);
   }
 
   virtual bool isCachePending() const { return m_imageValue->isCachePending(); }
diff --git a/third_party/WebKit/Source/core/dom/Element.idl b/third_party/WebKit/Source/core/dom/Element.idl
index 0cefbea0..a17419e1 100644
--- a/third_party/WebKit/Source/core/dom/Element.idl
+++ b/third_party/WebKit/Source/core/dom/Element.idl
@@ -34,6 +34,7 @@
     [CEReactions, Reflect] attribute DOMString id;
     [CEReactions, Reflect=class] attribute DOMString className;
     [SameObject, CEReactions, PerWorldBindings, PutForwards=value] readonly attribute DOMTokenList classList;
+    [Unscopable, CEReactions, Reflect] attribute DOMString slot;
 
     // PointerEvent
     //https://www.w3.org/TR/pointerevents/#extensions-to-the-element-interface
@@ -67,6 +68,9 @@
     [RaisesException] boolean matches(DOMString selectors);
     [RaisesException, ImplementedAs=matches, MeasureAs=ElementPrefixedMatchesSelector] boolean webkitMatchesSelector(DOMString selectors); // historical alias of .matches
 
+    [RaisesException, CallWith=ScriptState, MeasureAs=ElementAttachShadow] ShadowRoot attachShadow(ShadowRootInit shadowRootInitDict);
+    [PerWorldBindings, ImplementedAs=openShadowRoot] readonly attribute ShadowRoot? shadowRoot;
+
     HTMLCollection getElementsByTagName(DOMString localName);
     HTMLCollection getElementsByTagNameNS(DOMString? namespaceURI, DOMString localName);
     HTMLCollection getElementsByClassName(DOMString classNames);
@@ -74,21 +78,16 @@
     [RaisesException, CEReactions, CustomElementCallbacks] Element? insertAdjacentElement(DOMString where, Element element);
     [RaisesException] void insertAdjacentText(DOMString where, DOMString data);
 
+    // Mixin Slotable
+    // https://dom.spec.whatwg.org/#mixin-slotable
+    [ImplementedAs=assignedSlotForBinding] readonly attribute HTMLSlotElement? assignedSlot;
+
     // DOM Parsing and Serialization
     // https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#extensions-to-the-element-interface
     [TreatNullAs=NullString, CEReactions, CustomElementCallbacks, RaisesException=Setter] attribute DOMString innerHTML;
     [TreatNullAs=NullString, CEReactions, CustomElementCallbacks, RaisesException=Setter] attribute DOMString outerHTML;
     [CEReactions, CustomElementCallbacks, RaisesException] void insertAdjacentHTML(DOMString position, DOMString text);
 
-    // Shadow DOM
-    // https://w3c.github.io/webcomponents/spec/shadow/#extensions-to-element-interface
-    [RaisesException, CallWith=ScriptState, MeasureAs=ElementCreateShadowRoot] ShadowRoot createShadowRoot();
-    [RaisesException, CallWith=ScriptState, MeasureAs=ElementAttachShadow] ShadowRoot attachShadow(ShadowRootInit shadowRootInitDict);
-    NodeList getDestinationInsertionPoints();
-    [PerWorldBindings, ImplementedAs=openShadowRoot] readonly attribute ShadowRoot? shadowRoot;
-    [Unscopable, CEReactions, Reflect] attribute DOMString slot;
-    [ImplementedAs=assignedSlotForBinding] readonly attribute HTMLSlotElement assignedSlot;
-
     // Pointer Lock
     // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#extensions-to-the-element-interface
     [MeasureAs=ElementRequestPointerLock] void requestPointerLock();
@@ -122,6 +121,8 @@
 
     // Non-standard API
     [MeasureAs=ElementScrollIntoViewIfNeeded] void scrollIntoViewIfNeeded(optional boolean centerIfNeeded);
+    [RaisesException, CallWith=ScriptState, MeasureAs=ElementCreateShadowRoot] ShadowRoot createShadowRoot();
+    NodeList getDestinationInsertionPoints();
 
     // Experimental accessibility API
     [RuntimeEnabled=ComputedAccessibilityInfo] readonly attribute DOMString? computedRole;
diff --git a/third_party/WebKit/Source/core/dom/Text.idl b/third_party/WebKit/Source/core/dom/Text.idl
index 74cfdac..0ed45a8 100644
--- a/third_party/WebKit/Source/core/dom/Text.idl
+++ b/third_party/WebKit/Source/core/dom/Text.idl
@@ -26,8 +26,10 @@
     [NewObject, DoNotTestNewObject, RaisesException] Text splitText(unsigned long offset);
     [MeasureAs=TextWholeText] readonly attribute DOMString wholeText;
 
-    // Shadow DOM
-    // https://w3c.github.io/webcomponents/spec/shadow/#extensions-to-text-interface
+    // Mixin Slotable
+    // https://dom.spec.whatwg.org/#mixin-slotable
+    [ImplementedAs=assignedSlotForBinding] readonly attribute HTMLSlotElement? assignedSlot;
+
+    // Non-standard API:
     NodeList getDestinationInsertionPoints();
-    [ImplementedAs=assignedSlotForBinding] readonly attribute HTMLSlotElement assignedSlot;
 };
diff --git a/third_party/WebKit/Source/core/editing/Editor.cpp b/third_party/WebKit/Source/core/editing/Editor.cpp
index 1424270..8aea7a9 100644
--- a/third_party/WebKit/Source/core/editing/Editor.cpp
+++ b/third_party/WebKit/Source/core/editing/Editor.cpp
@@ -62,7 +62,7 @@
 #include "core/events/KeyboardEvent.h"
 #include "core/events/ScopedEventQueue.h"
 #include "core/events/TextEvent.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
@@ -490,7 +490,7 @@
     if (!layoutImage)
       return nullptr;
 
-    ImageResource* cachedImage = layoutImage->cachedImage();
+    ImageResourceContent* cachedImage = layoutImage->cachedImage();
     if (!cachedImage || cachedImage->errorOccurred())
       return nullptr;
     return cachedImage->getImage();
diff --git a/third_party/WebKit/Source/core/fetch/BUILD.gn b/third_party/WebKit/Source/core/fetch/BUILD.gn
index 6f1887b..b0aa502 100644
--- a/third_party/WebKit/Source/core/fetch/BUILD.gn
+++ b/third_party/WebKit/Source/core/fetch/BUILD.gn
@@ -23,6 +23,9 @@
     "FetchUtils.h",
     "ImageResource.cpp",
     "ImageResource.h",
+    "ImageResourceContent.cpp",
+    "ImageResourceContent.h",
+    "ImageResourceInfo.h",
     "IntegrityMetadata.cpp",
     "IntegrityMetadata.h",
     "MemoryCache.cpp",
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.cpp b/third_party/WebKit/Source/core/fetch/ImageResource.cpp
index 82152c1..bb2150f1 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/ImageResource.cpp
@@ -23,26 +23,20 @@
 
 #include "core/fetch/ImageResource.h"
 
-#include "core/fetch/ImageResourceObserver.h"
+#include "core/fetch/ImageResourceContent.h"
+#include "core/fetch/ImageResourceInfo.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/fetch/ResourceClient.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ResourceLoader.h"
 #include "core/fetch/ResourceLoadingLog.h"
-#include "core/svg/graphics/SVGImage.h"
 #include "platform/Histogram.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/SharedBuffer.h"
-#include "platform/geometry/IntSize.h"
-#include "platform/graphics/BitmapImage.h"
-#include "platform/graphics/PlaceholderImage.h"
 #include "platform/tracing/TraceEvent.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebCachePolicy.h"
 #include "wtf/CurrentTime.h"
-#include "wtf/HashCountedSet.h"
 #include "wtf/StdLibExtras.h"
-#include "wtf/Vector.h"
 #include <memory>
 #include <v8.h>
 
@@ -54,6 +48,83 @@
 constexpr double kFlushDelaySeconds = 1.;
 }  // namespace
 
+class ImageResource::ImageResourceInfoImpl final
+    : public GarbageCollectedFinalized<ImageResourceInfoImpl>,
+      public ImageResourceInfo {
+  USING_GARBAGE_COLLECTED_MIXIN(ImageResourceInfoImpl);
+
+ public:
+  ImageResourceInfoImpl(ImageResource* resource) : m_resource(resource) {
+    DCHECK(m_resource);
+  }
+  DEFINE_INLINE_VIRTUAL_TRACE() {
+    visitor->trace(m_resource);
+    ImageResourceInfo::trace(visitor);
+  }
+
+ private:
+  const KURL& url() const override { return m_resource->url(); }
+  bool isSchedulingReload() const override {
+    return m_resource->m_isSchedulingReload;
+  }
+  bool hasDevicePixelRatioHeaderValue() const override {
+    return m_resource->m_hasDevicePixelRatioHeaderValue;
+  }
+  float devicePixelRatioHeaderValue() const override {
+    return m_resource->m_devicePixelRatioHeaderValue;
+  }
+  const ResourceResponse& response() const override {
+    return m_resource->response();
+  }
+  Resource::Status getStatus() const override {
+    return m_resource->getStatus();
+  }
+  bool isPlaceholder() const override { return m_resource->isPlaceholder(); }
+  bool isCacheValidator() const override {
+    return m_resource->isCacheValidator();
+  }
+  bool schedulingReloadOrShouldReloadBrokenPlaceholder() const override {
+    return m_resource->m_isSchedulingReload ||
+           m_resource->shouldReloadBrokenPlaceholder();
+  }
+  bool isAccessAllowed(
+      SecurityOrigin* securityOrigin,
+      DoesCurrentFrameHaveSingleSecurityOrigin
+          doesCurrentFrameHasSingleSecurityOrigin) const override {
+    return m_resource->isAccessAllowed(securityOrigin,
+                                       doesCurrentFrameHasSingleSecurityOrigin);
+  }
+  bool hasCacheControlNoStoreHeader() const override {
+    return m_resource->hasCacheControlNoStoreHeader();
+  }
+  const ResourceError& resourceError() const override {
+    return m_resource->resourceError();
+  }
+
+  void decodeError(bool allDataReceived) override {
+    m_resource->decodeError(allDataReceived);
+  }
+  void setDecodedSize(size_t size) override {
+    m_resource->setDecodedSize(size);
+  }
+  void willAddClientOrObserver() override {
+    m_resource->willAddClientOrObserver(Resource::MarkAsReferenced);
+  }
+  void didRemoveClientOrObserver() override {
+    m_resource->didRemoveClientOrObserver();
+  }
+  void emulateLoadStartedForInspector(
+      ResourceFetcher* fetcher,
+      const KURL& url,
+      const AtomicString& initiatorName) override {
+    fetcher->emulateLoadStartedForInspector(m_resource.get(), url,
+                                            WebURLRequest::RequestContextImage,
+                                            initiatorName);
+  }
+
+  const Member<ImageResource> m_resource;
+};
+
 class ImageResource::ImageResourceFactory : public ResourceFactory {
   STACK_ALLOCATED();
 
@@ -64,7 +135,7 @@
   Resource* create(const ResourceRequest& request,
                    const ResourceLoaderOptions& options,
                    const String&) const override {
-    return new ImageResource(request, options,
+    return new ImageResource(request, options, ImageResourceContent::create(),
                              m_fetchRequest->placeholderImageRequestType() ==
                                  FetchRequest::AllowPlaceholder);
   }
@@ -108,43 +179,35 @@
   return resource;
 }
 
+ImageResource* ImageResource::create(const ResourceRequest& request) {
+  return new ImageResource(request, ResourceLoaderOptions(),
+                           ImageResourceContent::create(), false);
+}
+
 ImageResource::ImageResource(const ResourceRequest& resourceRequest,
                              const ResourceLoaderOptions& options,
+                             ImageResourceContent* content,
                              bool isPlaceholder)
     : Resource(resourceRequest, Image, options),
+      m_content(content),
       m_devicePixelRatioHeaderValue(1.0),
-      m_image(nullptr),
       m_hasDevicePixelRatioHeaderValue(false),
       m_isSchedulingReload(false),
       m_isPlaceholder(isPlaceholder),
-      m_flushTimer(this, &ImageResource::flushImageIfNeeded),
-      m_isRefetchableDataFromDiskCache(true) {
+      m_flushTimer(this, &ImageResource::flushImageIfNeeded) {
+  DCHECK(getContent());
   RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this;
-}
-
-ImageResource::ImageResource(blink::Image* image,
-                             const ResourceLoaderOptions& options)
-    : Resource(ResourceRequest(""), Image, options),
-      m_devicePixelRatioHeaderValue(1.0),
-      m_image(image),
-      m_hasDevicePixelRatioHeaderValue(false),
-      m_isSchedulingReload(false),
-      m_isPlaceholder(false),
-      m_flushTimer(this, &ImageResource::flushImageIfNeeded),
-      m_isRefetchableDataFromDiskCache(true) {
-  RESOURCE_LOADING_DVLOG(1) << "new ImageResource(Image) " << this;
-  setStatus(Cached);
+  getContent()->setImageResourceInfo(new ImageResourceInfoImpl(this));
 }
 
 ImageResource::~ImageResource() {
   RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this;
-  clearImage();
 }
 
 DEFINE_TRACE(ImageResource) {
   visitor->trace(m_multipartParser);
+  visitor->trace(m_content);
   Resource::trace(visitor);
-  ImageObserver::trace(visitor);
   MultipartImageResourceParser::Client::trace(visitor);
 }
 
@@ -157,16 +220,13 @@
   Resource::checkNotify();
 }
 
-void ImageResource::markObserverFinished(ImageResourceObserver* observer) {
-  auto it = m_observers.find(observer);
-  if (it == m_observers.end())
-    return;
-  m_observers.remove(it);
-  m_finishedObservers.add(observer);
+bool ImageResource::hasClientsOrObservers() const {
+  return Resource::hasClientsOrObservers() || getContent()->hasObservers();
 }
 
 void ImageResource::didAddClient(ResourceClient* client) {
-  DCHECK((m_multipartParser && isLoading()) || !data() || m_image);
+  DCHECK((m_multipartParser && isLoading()) || !data() ||
+         getContent()->hasImage());
 
   // Don't notify observers and clients of completion if this ImageResource is
   // about to be reloaded.
@@ -176,103 +236,31 @@
   Resource::didAddClient(client);
 }
 
-void ImageResource::addObserver(ImageResourceObserver* observer) {
-  willAddClientOrObserver(MarkAsReferenced);
-
-  m_observers.add(observer);
-
-  if (isCacheValidator())
-    return;
-
-  // When the response is not multipart, if |data()| exists, |m_image| must be
-  // created. This is assured that |updateImage()| is called when |appendData()|
-  // is called.
-  //
-  // On the other hand, when the response is multipart, |updateImage()| is not
-  // called in |appendData()|, which means |m_image| might not be created even
-  // when |data()| exists. This is intentional since creating a |m_image| on
-  // receiving data might destroy an existing image in a previous part.
-  DCHECK((m_multipartParser && isLoading()) || !data() || m_image);
-
-  if (m_image && !m_image->isNull()) {
-    observer->imageChanged(this);
-  }
-
-  if (isLoaded() && m_observers.contains(observer) && !m_isSchedulingReload &&
-      !shouldReloadBrokenPlaceholder()) {
-    markObserverFinished(observer);
-    observer->imageNotifyFinished(this);
-  }
-}
-
-void ImageResource::removeObserver(ImageResourceObserver* observer) {
-  DCHECK(observer);
-
-  auto it = m_observers.find(observer);
-  if (it != m_observers.end()) {
-    m_observers.remove(it);
-  } else {
-    it = m_finishedObservers.find(observer);
-    DCHECK(it != m_finishedObservers.end());
-    m_finishedObservers.remove(it);
-  }
-  didRemoveClientOrObserver();
-}
-
-static void priorityFromObserver(const ImageResourceObserver* observer,
-                                 ResourcePriority& priority) {
-  ResourcePriority nextPriority = observer->computeResourcePriority();
-  if (nextPriority.visibility == ResourcePriority::NotVisible)
-    return;
-  priority.visibility = ResourcePriority::Visible;
-  priority.intraPriorityValue += nextPriority.intraPriorityValue;
-}
-
-ResourcePriority ImageResource::priorityFromObservers() {
-  ResourcePriority priority;
-
-  for (const auto& it : m_finishedObservers)
-    priorityFromObserver(it.key, priority);
-  for (const auto& it : m_observers)
-    priorityFromObserver(it.key, priority);
-
-  return priority;
-}
-
 void ImageResource::destroyDecodedDataForFailedRevalidation() {
-  clearImage();
+  getContent()->clearImage();
   setDecodedSize(0);
 }
 
 void ImageResource::destroyDecodedDataIfPossible() {
-  if (!m_image)
-    return;
-  CHECK(!errorOccurred());
-  m_image->destroyDecodedData();
-  if (!isPreloaded() && m_isRefetchableDataFromDiskCache) {
+  getContent()->destroyDecodedData();
+  if (getContent()->hasImage() && !isPreloaded() &&
+      getContent()->isRefetchableDataFromDiskCache()) {
     UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer.EstimatedDroppableEncodedSize",
                             encodedSize() / 1024);
   }
 }
 
-void ImageResource::doResetAnimation() {
-  if (m_image)
-    m_image->resetAnimation();
-}
-
 void ImageResource::allClientsAndObserversRemoved() {
-  if (m_image) {
-    CHECK(!errorOccurred());
-    // If possible, delay the resetting until back at the event loop. Doing so
-    // after a conservative GC prevents resetAnimation() from upsetting ongoing
-    // animation updates (crbug.com/613709)
-    if (!ThreadHeap::willObjectBeLazilySwept(this)) {
-      Platform::current()->currentThread()->getWebTaskRunner()->postTask(
-          BLINK_FROM_HERE, WTF::bind(&ImageResource::doResetAnimation,
-                                     wrapWeakPersistent(this)));
-    } else {
-      m_image->resetAnimation();
-    }
+  CHECK(!getContent()->hasImage() || !errorOccurred());
+  // If possible, delay the resetting until back at the event loop. Doing so
+  // after a conservative GC prevents resetAnimation() from upsetting ongoing
+  // animation updates (crbug.com/613709)
+  if (!ThreadHeap::willObjectBeLazilySwept(this)) {
+    Platform::current()->currentThread()->getWebTaskRunner()->postTask(
+        BLINK_FROM_HERE, WTF::bind(&ImageResourceContent::doResetAnimation,
+                                   wrapWeakPersistent(getContent())));
+  } else {
+    getContent()->doResetAnimation();
   }
   if (m_multipartParser)
     m_multipartParser->cancel();
@@ -282,9 +270,7 @@
 PassRefPtr<const SharedBuffer> ImageResource::resourceBuffer() const {
   if (data())
     return data();
-  if (m_image)
-    return m_image->data();
-  return nullptr;
+  return getContent()->resourceBuffer();
 }
 
 void ImageResource::appendData(const char* data, size_t length) {
@@ -294,13 +280,10 @@
   } else {
     Resource::appendData(data, length);
 
-    // If we don't have the size available yet, then update immediately since
-    // we need to know the image size as soon as possible. Likewise for
-    // animated images, update right away since we shouldn't throttle animated
-    // images.
-    if (m_sizeAvailable == Image::SizeUnavailable ||
-        (m_image && m_image->maybeAnimated())) {
-      updateImage(false);
+    // Update the image immediately if needed.
+    if (getContent()->shouldUpdateImageImmediately()) {
+      getContent()->updateImage(this->data(),
+                                ImageResourceContent::KeepExistingImage, false);
       return;
     }
 
@@ -328,193 +311,34 @@
   // to call |updateImage()|.
   if (isLoading()) {
     m_lastFlushTime = WTF::monotonicallyIncreasingTime();
-    updateImage(false);
+    getContent()->updateImage(this->data(),
+                              ImageResourceContent::KeepExistingImage, false);
   }
 }
 
-std::pair<blink::Image*, float> ImageResource::brokenImage(
-    float deviceScaleFactor) {
-  if (deviceScaleFactor >= 2) {
-    DEFINE_STATIC_REF(blink::Image, brokenImageHiRes,
-                      (blink::Image::loadPlatformResource("missingImage@2x")));
-    return std::make_pair(brokenImageHiRes, 2);
-  }
-
-  DEFINE_STATIC_REF(blink::Image, brokenImageLoRes,
-                    (blink::Image::loadPlatformResource("missingImage")));
-  return std::make_pair(brokenImageLoRes, 1);
-}
-
 bool ImageResource::willPaintBrokenImage() const {
   return errorOccurred();
 }
 
-blink::Image* ImageResource::getImage() {
-  if (errorOccurred()) {
-    // Returning the 1x broken image is non-ideal, but we cannot reliably access
-    // the appropriate deviceScaleFactor from here. It is critical that callers
-    // use ImageResource::brokenImage() when they need the real,
-    // deviceScaleFactor-appropriate broken image icon.
-    return brokenImage(1).first;
-  }
+void ImageResource::decodeError(bool allDataReceived) {
+  size_t size = encodedSize();
 
-  if (m_image)
-    return m_image.get();
-
-  return blink::Image::nullImage();
-}
-
-bool ImageResource::usesImageContainerSize() const {
-  if (m_image)
-    return m_image->usesContainerSize();
-
-  return false;
-}
-
-bool ImageResource::imageHasRelativeSize() const {
-  if (m_image)
-    return m_image->hasRelativeSize();
-
-  return false;
-}
-
-LayoutSize ImageResource::imageSize(
-    RespectImageOrientationEnum shouldRespectImageOrientation,
-    float multiplier,
-    SizeType sizeType) {
-  if (!m_image)
-    return LayoutSize();
-
-  LayoutSize size;
-
-  if (m_image->isBitmapImage() &&
-      shouldRespectImageOrientation == RespectImageOrientation) {
-    size =
-        LayoutSize(toBitmapImage(m_image.get())->sizeRespectingOrientation());
-  } else {
-    size = LayoutSize(m_image->size());
-  }
-
-  if (sizeType == IntrinsicCorrectedToDPR && m_hasDevicePixelRatioHeaderValue &&
-      m_devicePixelRatioHeaderValue > 0)
-    multiplier = 1 / m_devicePixelRatioHeaderValue;
-
-  if (multiplier == 1 || m_image->hasRelativeSize())
-    return size;
-
-  // Don't let images that have a width/height >= 1 shrink below 1 when zoomed.
-  LayoutSize minimumSize(
-      size.width() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit(),
-      LayoutUnit(size.height() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit()));
-  size.scale(multiplier);
-  size.clampToMinimumSize(minimumSize);
-  return size;
-}
-
-void ImageResource::notifyObservers(NotifyFinishOption notifyingFinishOption,
-                                    const IntRect* changeRect) {
-  for (auto* observer : m_finishedObservers.asVector()) {
-    if (m_finishedObservers.contains(observer))
-      observer->imageChanged(this, changeRect);
-  }
-  for (auto* observer : m_observers.asVector()) {
-    if (m_observers.contains(observer)) {
-      observer->imageChanged(this, changeRect);
-      if (notifyingFinishOption == ShouldNotifyFinish &&
-          m_observers.contains(observer) && !m_isSchedulingReload &&
-          !shouldReloadBrokenPlaceholder()) {
-        markObserverFinished(observer);
-        observer->imageNotifyFinished(this);
-      }
-    }
-  }
-}
-
-void ImageResource::clear() {
-  clearImage();
   clearData();
   setEncodedSize(0);
-}
+  if (!errorOccurred())
+    setStatus(DecodeError);
 
-inline void ImageResource::createImage() {
-  // Create the image if it doesn't yet exist.
-  if (m_image)
-    return;
-
-  if (response().mimeType() == "image/svg+xml") {
-    m_image = SVGImage::create(this);
-  } else {
-    m_image = BitmapImage::create(this);
-  }
-}
-
-inline void ImageResource::clearImage() {
-  if (!m_image)
-    return;
-  int64_t length = m_image->data() ? m_image->data()->size() : 0;
-  v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-length);
-
-  // If our Image has an observer, it's always us so we need to clear the back
-  // pointer before dropping our reference.
-  m_image->clearImageObserver();
-  m_image.clear();
-  m_sizeAvailable = Image::SizeUnavailable;
-}
-
-void ImageResource::updateImage(bool allDataReceived) {
-  TRACE_EVENT0("blink", "ImageResource::updateImage");
-
-  if (data())
-    createImage();
-
-  // Have the image update its data from its internal buffer. It will not do
-  // anything now, but will delay decoding until queried for info (like size or
-  // specific image frames).
-  if (data()) {
-    DCHECK(m_image);
-    m_sizeAvailable = m_image->setData(data(), allDataReceived);
+  if (!allDataReceived && loader()) {
+    // TODO(hiroshige): Do not call didFinishLoading() directly.
+    loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size);
   }
 
-  // Go ahead and tell our observers to try to draw if we have either received
-  // all the data or the size is known. Each chunk from the network causes
-  // observers to repaint, which will force that chunk to decode.
-  if (m_sizeAvailable == Image::SizeUnavailable && !allDataReceived)
-    return;
-
-  if (m_isPlaceholder && allDataReceived && m_image && !m_image->isNull()) {
-    if (m_sizeAvailable == Image::SizeAvailable) {
-      // TODO(sclittle): Show the original image if the response consists of the
-      // entire image, such as if the entire image response body is smaller than
-      // the requested range.
-      IntSize dimensions = m_image->size();
-      clearImage();
-      m_image = PlaceholderImage::create(this, dimensions);
-    } else {
-      // Clear the image so that it gets treated like a decoding error, since
-      // the attempt to build a placeholder image failed.
-      clearImage();
-    }
-  }
-
-  if (!m_image || m_image->isNull()) {
-    size_t size = encodedSize();
-    clear();
-    if (!errorOccurred())
-      setStatus(DecodeError);
-    if (!allDataReceived && loader()) {
-      loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size);
-    }
-    memoryCache()->remove(this);
-  }
-
-  // It would be nice to only redraw the decoded band of the image, but with the
-  // current design (decoding delayed until painting) that seems hard.
-  notifyObservers(allDataReceived ? ShouldNotifyFinish : DoNotNotifyFinish);
+  memoryCache()->remove(this);
 }
 
 void ImageResource::updateImageAndClearBuffer() {
-  clearImage();
-  updateImage(true);
+  getContent()->updateImage(data(), ImageResourceContent::ClearExistingImage,
+                            true);
   clearData();
 }
 
@@ -524,7 +348,8 @@
     if (data())
       updateImageAndClearBuffer();
   } else {
-    updateImage(true);
+    getContent()->updateImage(data(), ImageResourceContent::KeepExistingImage,
+                              true);
     // As encoded image data can be created from m_image  (see
     // ImageResource::resourceBuffer(), we don't have to keep m_data. Let's
     // clear this. As for the lifetimes of m_image and m_data, see this
@@ -538,9 +363,12 @@
 void ImageResource::error(const ResourceError& error) {
   if (m_multipartParser)
     m_multipartParser->cancel();
-  clear();
+  // TODO(hiroshige): Move setEncodedSize() call to Resource::error() if it
+  // is really needed, or remove it otherwise.
+  setEncodedSize(0);
   Resource::error(error);
-  notifyObservers(ShouldNotifyFinish);
+  getContent()->clearImageAndNotifyObservers(
+      ImageResourceContent::ShouldNotifyFinish);
 }
 
 void ImageResource::responseReceived(
@@ -567,55 +395,6 @@
   }
 }
 
-void ImageResource::decodedSizeChangedTo(const blink::Image* image,
-                                         size_t newSize) {
-  if (!image || image != m_image)
-    return;
-
-  setDecodedSize(newSize);
-}
-
-bool ImageResource::shouldPauseAnimation(const blink::Image* image) {
-  if (!image || image != m_image)
-    return false;
-
-  for (const auto& it : m_finishedObservers)
-    if (it.key->willRenderImage())
-      return false;
-
-  for (const auto& it : m_observers)
-    if (it.key->willRenderImage())
-      return false;
-
-  return true;
-}
-
-void ImageResource::animationAdvanced(const blink::Image* image) {
-  if (!image || image != m_image)
-    return;
-  notifyObservers(DoNotNotifyFinish);
-}
-
-void ImageResource::updateImageAnimationPolicy() {
-  if (!m_image)
-    return;
-
-  ImageAnimationPolicy newPolicy = ImageAnimationPolicyAllowed;
-  for (const auto& it : m_finishedObservers) {
-    if (it.key->getImageAnimationPolicy(newPolicy))
-      break;
-  }
-  for (const auto& it : m_observers) {
-    if (it.key->getImageAnimationPolicy(newPolicy))
-      break;
-  }
-
-  if (m_image->animationPolicy() != newPolicy) {
-    m_image->resetAnimation();
-    m_image->setAnimationPolicy(newPolicy);
-  }
-}
-
 static bool isLoFiImage(const ImageResource& resource) {
   if (resource.resourceRequest().loFiState() != WebURLRequest::LoFiOn)
     return false;
@@ -653,8 +432,10 @@
     // clear() and notifyObservers(), so there's no need to call these again
     // here.
   } else {
-    clear();
-    notifyObservers(DoNotNotifyFinish);
+    clearData();
+    setEncodedSize(0);
+    getContent()->clearImageAndNotifyObservers(
+        ImageResourceContent::DoNotNotifyFinish);
   }
 
   setStatus(NotStarted);
@@ -665,13 +446,6 @@
   fetcher->startLoad(this);
 }
 
-void ImageResource::changedInRect(const blink::Image* image,
-                                  const IntRect& rect) {
-  if (!image || image != m_image)
-    return;
-  notifyObservers(DoNotNotifyFinish, &rect);
-}
-
 void ImageResource::onePartInMultipartReceived(
     const ResourceResponse& response) {
   DCHECK(m_multipartParser);
@@ -703,16 +477,32 @@
   Resource::appendData(bytes, size);
 }
 
-bool ImageResource::isAccessAllowed(SecurityOrigin* securityOrigin) {
+bool ImageResource::isAccessAllowed(
+    SecurityOrigin* securityOrigin,
+    ImageResourceInfo::DoesCurrentFrameHaveSingleSecurityOrigin
+        doesCurrentFrameHasSingleSecurityOrigin) const {
   if (response().wasFetchedViaServiceWorker()) {
     return response().serviceWorkerResponseType() !=
            WebServiceWorkerResponseTypeOpaque;
   }
-  if (!getImage()->currentFrameHasSingleSecurityOrigin())
+  if (doesCurrentFrameHasSingleSecurityOrigin !=
+      ImageResourceInfo::HasSingleSecurityOrigin)
     return false;
   if (passesAccessControlCheck(securityOrigin))
     return true;
   return !securityOrigin->taintsCanvas(response().url());
 }
 
+ImageResourceContent* ImageResource::getContent() {
+  return m_content;
+}
+
+const ImageResourceContent* ImageResource::getContent() const {
+  return m_content;
+}
+
+ResourcePriority ImageResource::priorityFromObservers() {
+  return getContent()->priorityFromObservers();
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.h b/third_party/WebKit/Source/core/fetch/ImageResource.h
index 2d2b657d..89643c20 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.h
+++ b/third_party/WebKit/Source/core/fetch/ImageResource.h
@@ -24,89 +24,50 @@
 #define ImageResource_h
 
 #include "core/CoreExport.h"
+#include "core/fetch/ImageResourceInfo.h"
 #include "core/fetch/MultipartImageResourceParser.h"
 #include "core/fetch/Resource.h"
-#include "platform/geometry/IntRect.h"
-#include "platform/geometry/IntSizeHash.h"
-#include "platform/geometry/LayoutSize.h"
-#include "platform/graphics/Image.h"
-#include "platform/graphics/ImageObserver.h"
-#include "platform/graphics/ImageOrientation.h"
-#include "wtf/HashMap.h"
+#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
 #include <memory>
 
 namespace blink {
 
 class FetchRequest;
-class ImageResourceObserver;
-class MemoryCache;
+class ImageResourceContent;
 class ResourceClient;
 class ResourceFetcher;
 class SecurityOrigin;
 
-// ImageResource class represents an image type resource.
+// ImageResource implements blink::Resource interface and image-specific logic
+// for loading images.
+// Image-related things (blink::Image and ImageResourceObserver) are handled by
+// ImageResourceContent.
+// Most users should use ImageResourceContent instead of ImageResource.
+// https://docs.google.com/document/d/1O-fB83mrE0B_V8gzXNqHgmRLCvstTB4MMi3RnVLr8bE/edit?usp=sharing
 //
-// As for the lifetimes of m_image and m_data, see this document:
+// As for the lifetimes of ImageResourceContent::m_image and m_data, see this
+// document:
 // https://docs.google.com/document/d/1v0yTAZ6wkqX2U_M6BNIGUJpM1s0TIw1VsqpxoL7aciY/edit?usp=sharing
 class CORE_EXPORT ImageResource final
     : public Resource,
-      public ImageObserver,
       public MultipartImageResourceParser::Client {
-  friend class MemoryCache;
   USING_GARBAGE_COLLECTED_MIXIN(ImageResource);
 
  public:
   using ClientType = ResourceClient;
 
+  // Use ImageResourceContent::fetch() unless ImageResource is required.
+  // TODO(hiroshige): Make fetch() private.
   static ImageResource* fetch(FetchRequest&, ResourceFetcher*);
 
-  static ImageResource* create(blink::Image* image) {
-    return new ImageResource(image, ResourceLoaderOptions());
-  }
-
-  static ImageResource* create(const ResourceRequest& request) {
-    return new ImageResource(request, ResourceLoaderOptions(), false);
-  }
+  // TODO(hiroshige): Make create() test-only by refactoring ImageDocument.
+  static ImageResource* create(const ResourceRequest&);
 
   ~ImageResource() override;
 
-  blink::Image*
-  getImage();  // Returns the nullImage() if the image is not available yet.
-  bool hasImage() const { return m_image.get(); }
-
-  static std::pair<blink::Image*, float> brokenImage(
-      float deviceScaleFactor);  // Returns an image and the image's resolution
-                                 // scale factor.
-  bool willPaintBrokenImage() const;
-
-  bool usesImageContainerSize() const;
-  bool imageHasRelativeSize() const;
-  // The device pixel ratio we got from the server for this image, or 1.0.
-  float devicePixelRatioHeaderValue() const {
-    return m_devicePixelRatioHeaderValue;
-  }
-  bool hasDevicePixelRatioHeaderValue() const {
-    return m_hasDevicePixelRatioHeaderValue;
-  }
-
-  enum SizeType {
-    // Report the intrinsic size.
-    IntrinsicSize,
-
-    // Report the intrinsic size corrected to account for image density.
-    IntrinsicCorrectedToDPR,
-  };
-
-  // This method takes a zoom multiplier that can be used to increase the
-  // natural size of the image by the zoom.
-  LayoutSize imageSize(
-      RespectImageOrientationEnum shouldRespectImageOrientation,
-      float multiplier,
-      SizeType = IntrinsicSize);
-
-  bool isAccessAllowed(SecurityOrigin*);
-
-  void updateImageAnimationPolicy();
+  ImageResourceContent* getContent();
+  const ImageResourceContent* getContent() const;
 
   enum class ReloadCachePolicy {
     UseExistingPolicy = 0,  // Don't modify the request's cache policy.
@@ -122,9 +83,6 @@
 
   void didAddClient(ResourceClient*) override;
 
-  void addObserver(ImageResourceObserver*);
-  void removeObserver(ImageResourceObserver*);
-
   ResourcePriority priorityFromObservers() override;
 
   void allClientsAndObserversRemoved() override;
@@ -141,13 +99,6 @@
 
   bool isImage() const override { return true; }
 
-  // ImageObserver
-  void decodedSizeChangedTo(const blink::Image*, size_t newSize) override;
-
-  bool shouldPauseAnimation(const blink::Image*) override;
-  void animationAdvanced(const blink::Image*) override;
-  void changedInRect(const blink::Image*, const IntRect&) override;
-
   // MultipartImageResourceParser::Client
   void onePartInMultipartReceived(const ResourceResponse&) final;
   void multipartDataReceived(const char*, size_t) final;
@@ -159,63 +110,53 @@
     return m_isPlaceholder && willPaintBrokenImage();
   }
 
-  void setNotRefetchableDataFromDiskCache() {
-    m_isRefetchableDataFromDiskCache = false;
-  }
-
   DECLARE_VIRTUAL_TRACE();
 
  private:
-  explicit ImageResource(blink::Image*, const ResourceLoaderOptions&);
-
   enum class MultipartParsingState : uint8_t {
     WaitingForFirstPart,
     ParsingFirstPart,
     FinishedParsingFirstPart,
   };
 
+  class ImageResourceInfoImpl;
   class ImageResourceFactory;
 
   ImageResource(const ResourceRequest&,
                 const ResourceLoaderOptions&,
+                ImageResourceContent*,
                 bool isPlaceholder);
 
-  bool hasClientsOrObservers() const override {
-    return Resource::hasClientsOrObservers() || !m_observers.isEmpty() ||
-           !m_finishedObservers.isEmpty();
-  }
-  void clear();
+  // Only for ImageResourceInfoImpl.
+  void decodeError(bool allDataReceived);
+  bool isAccessAllowed(
+      SecurityOrigin*,
+      ImageResourceInfo::DoesCurrentFrameHaveSingleSecurityOrigin) const;
 
-  void createImage();
-  void updateImage(bool allDataReceived);
+  bool hasClientsOrObservers() const override;
+
   void updateImageAndClearBuffer();
-  void clearImage();
-  enum NotifyFinishOption { ShouldNotifyFinish, DoNotNotifyFinish };
-  // If not null, changeRect is the changed part of the image.
-  void notifyObservers(NotifyFinishOption, const IntRect* changeRect = nullptr);
-
-  void ensureImage();
 
   void checkNotify() override;
-  void notifyObserversInternal();
-  void markObserverFinished(ImageResourceObserver*);
-
-  void doResetAnimation();
 
   void destroyDecodedDataIfPossible() override;
   void destroyDecodedDataForFailedRevalidation() override;
 
   void flushImageIfNeeded(TimerBase*);
 
+  bool willPaintBrokenImage() const;
+
+  Member<ImageResourceContent> m_content;
+
+  // TODO(hiroshige): move |m_devicePixelRatioHeaderValue| and
+  // |m_hasDevicePixelRatioHeaderValue| to ImageResourceContent and update
+  // it via ImageResourceContent::updateImage().
   float m_devicePixelRatioHeaderValue;
 
   Member<MultipartImageResourceParser> m_multipartParser;
-  RefPtr<blink::Image> m_image;
   MultipartParsingState m_multipartParsingState =
       MultipartParsingState::WaitingForFirstPart;
   bool m_hasDevicePixelRatioHeaderValue;
-  HashCountedSet<ImageResourceObserver*> m_observers;
-  HashCountedSet<ImageResourceObserver*> m_finishedObservers;
 
   // Indicates if the ImageResource is currently scheduling a reload, e.g.
   // because reloadIfLoFi() was called.
@@ -227,11 +168,6 @@
 
   Timer<ImageResource> m_flushTimer;
   double m_lastFlushTime = 0.;
-  Image::SizeAvailability m_sizeAvailable = Image::SizeUnavailable;
-
-  // Indicates if this resource's encoded image data can be purged and refetched
-  // from disk cache to save memory usage. See crbug/664437.
-  bool m_isRefetchableDataFromDiskCache;
 };
 
 DEFINE_RESOURCE_TYPE_CASTS(Image);
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceContent.cpp b/third_party/WebKit/Source/core/fetch/ImageResourceContent.cpp
new file mode 100644
index 0000000..4387c12
--- /dev/null
+++ b/third_party/WebKit/Source/core/fetch/ImageResourceContent.cpp
@@ -0,0 +1,475 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fetch/ImageResourceContent.h"
+
+#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceInfo.h"
+#include "core/fetch/ImageResourceObserver.h"
+#include "core/svg/graphics/SVGImage.h"
+#include "platform/Histogram.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/SharedBuffer.h"
+#include "platform/geometry/IntSize.h"
+#include "platform/graphics/BitmapImage.h"
+#include "platform/graphics/PlaceholderImage.h"
+#include "platform/tracing/TraceEvent.h"
+#include "wtf/StdLibExtras.h"
+#include "wtf/Vector.h"
+#include <memory>
+#include <v8.h>
+
+namespace blink {
+namespace {
+class NullImageResourceInfo final
+    : public GarbageCollectedFinalized<NullImageResourceInfo>,
+      public ImageResourceInfo {
+  USING_GARBAGE_COLLECTED_MIXIN(NullImageResourceInfo);
+
+ public:
+  NullImageResourceInfo() {}
+
+  DEFINE_INLINE_VIRTUAL_TRACE() { ImageResourceInfo::trace(visitor); }
+
+ private:
+  const KURL& url() const override { return m_url; }
+  bool isSchedulingReload() const override { return false; }
+  bool hasDevicePixelRatioHeaderValue() const override { return false; }
+  float devicePixelRatioHeaderValue() const override { return 1.0; }
+  const ResourceResponse& response() const override { return m_response; }
+  ResourceStatus getStatus() const override { return ResourceStatus::Cached; }
+  bool isPlaceholder() const override { return false; }
+  bool isCacheValidator() const override { return false; }
+  bool schedulingReloadOrShouldReloadBrokenPlaceholder() const override {
+    return false;
+  }
+  bool isAccessAllowed(
+      SecurityOrigin*,
+      DoesCurrentFrameHaveSingleSecurityOrigin) const override {
+    return true;
+  }
+  bool hasCacheControlNoStoreHeader() const override { return false; }
+  const ResourceError& resourceError() const override { return m_error; }
+
+  void decodeError(bool allDataReceived) override {}
+  void setDecodedSize(size_t) override {}
+  void willAddClientOrObserver() override {}
+  void didRemoveClientOrObserver() override {}
+  void emulateLoadStartedForInspector(
+      ResourceFetcher*,
+      const KURL&,
+      const AtomicString& initiatorName) override {}
+
+  const KURL m_url;
+  const ResourceResponse m_response;
+  const ResourceError m_error;
+};
+
+}  // namespace
+
+ImageResourceContent::ImageResourceContent(PassRefPtr<blink::Image> image)
+    : m_image(image), m_isRefetchableDataFromDiskCache(true) {
+  DEFINE_STATIC_LOCAL(NullImageResourceInfo, nullInfo,
+                      (new NullImageResourceInfo()));
+  m_info = &nullInfo;
+}
+
+ImageResourceContent* ImageResourceContent::fetch(FetchRequest& request,
+                                                  ResourceFetcher* fetcher) {
+  // TODO(hiroshige): Remove direct references to ImageResource by making
+  // the dependencies around ImageResource and ImageResourceContent cleaner.
+  ImageResource* resource = ImageResource::fetch(request, fetcher);
+  if (!resource)
+    return nullptr;
+  return resource->getContent();
+}
+
+void ImageResourceContent::setImageResourceInfo(ImageResourceInfo* info) {
+  m_info = info;
+}
+
+DEFINE_TRACE(ImageResourceContent) {
+  visitor->trace(m_info);
+  ImageObserver::trace(visitor);
+}
+
+void ImageResourceContent::markObserverFinished(
+    ImageResourceObserver* observer) {
+  auto it = m_observers.find(observer);
+  if (it == m_observers.end())
+    return;
+  m_observers.remove(it);
+  m_finishedObservers.add(observer);
+}
+
+void ImageResourceContent::addObserver(ImageResourceObserver* observer) {
+  m_info->willAddClientOrObserver();
+
+  m_observers.add(observer);
+
+  if (m_info->isCacheValidator())
+    return;
+
+  if (m_image && !m_image->isNull()) {
+    observer->imageChanged(this);
+  }
+
+  if (isLoaded() && m_observers.contains(observer) &&
+      !m_info->schedulingReloadOrShouldReloadBrokenPlaceholder()) {
+    markObserverFinished(observer);
+    observer->imageNotifyFinished(this);
+  }
+}
+
+void ImageResourceContent::removeObserver(ImageResourceObserver* observer) {
+  DCHECK(observer);
+
+  auto it = m_observers.find(observer);
+  if (it != m_observers.end()) {
+    m_observers.remove(it);
+  } else {
+    it = m_finishedObservers.find(observer);
+    DCHECK(it != m_finishedObservers.end());
+    m_finishedObservers.remove(it);
+  }
+  m_info->didRemoveClientOrObserver();
+}
+
+static void priorityFromObserver(const ImageResourceObserver* observer,
+                                 ResourcePriority& priority) {
+  ResourcePriority nextPriority = observer->computeResourcePriority();
+  if (nextPriority.visibility == ResourcePriority::NotVisible)
+    return;
+  priority.visibility = ResourcePriority::Visible;
+  priority.intraPriorityValue += nextPriority.intraPriorityValue;
+}
+
+ResourcePriority ImageResourceContent::priorityFromObservers() const {
+  ResourcePriority priority;
+
+  for (const auto& it : m_finishedObservers)
+    priorityFromObserver(it.key, priority);
+  for (const auto& it : m_observers)
+    priorityFromObserver(it.key, priority);
+
+  return priority;
+}
+
+void ImageResourceContent::destroyDecodedData() {
+  if (!m_image)
+    return;
+  CHECK(!errorOccurred());
+  m_image->destroyDecodedData();
+}
+
+void ImageResourceContent::doResetAnimation() {
+  if (m_image)
+    m_image->resetAnimation();
+}
+
+PassRefPtr<const SharedBuffer> ImageResourceContent::resourceBuffer() const {
+  if (m_image)
+    return m_image->data();
+  return nullptr;
+}
+
+bool ImageResourceContent::shouldUpdateImageImmediately() const {
+  // If we don't have the size available yet, then update immediately since
+  // we need to know the image size as soon as possible. Likewise for
+  // animated images, update right away since we shouldn't throttle animated
+  // images.
+  return m_sizeAvailable == Image::SizeUnavailable ||
+         (m_image && m_image->maybeAnimated());
+}
+
+std::pair<blink::Image*, float> ImageResourceContent::brokenImage(
+    float deviceScaleFactor) {
+  if (deviceScaleFactor >= 2) {
+    DEFINE_STATIC_REF(blink::Image, brokenImageHiRes,
+                      (blink::Image::loadPlatformResource("missingImage@2x")));
+    return std::make_pair(brokenImageHiRes, 2);
+  }
+
+  DEFINE_STATIC_REF(blink::Image, brokenImageLoRes,
+                    (blink::Image::loadPlatformResource("missingImage")));
+  return std::make_pair(brokenImageLoRes, 1);
+}
+
+blink::Image* ImageResourceContent::getImage() {
+  if (errorOccurred()) {
+    // Returning the 1x broken image is non-ideal, but we cannot reliably access
+    // the appropriate deviceScaleFactor from here. It is critical that callers
+    // use ImageResourceContent::brokenImage() when they need the real,
+    // deviceScaleFactor-appropriate broken image icon.
+    return brokenImage(1).first;
+  }
+
+  if (m_image)
+    return m_image.get();
+
+  return blink::Image::nullImage();
+}
+
+bool ImageResourceContent::usesImageContainerSize() const {
+  if (m_image)
+    return m_image->usesContainerSize();
+
+  return false;
+}
+
+bool ImageResourceContent::imageHasRelativeSize() const {
+  if (m_image)
+    return m_image->hasRelativeSize();
+
+  return false;
+}
+
+LayoutSize ImageResourceContent::imageSize(
+    RespectImageOrientationEnum shouldRespectImageOrientation,
+    float multiplier,
+    SizeType sizeType) {
+  if (!m_image)
+    return LayoutSize();
+
+  LayoutSize size;
+
+  if (m_image->isBitmapImage() &&
+      shouldRespectImageOrientation == RespectImageOrientation) {
+    size =
+        LayoutSize(toBitmapImage(m_image.get())->sizeRespectingOrientation());
+  } else {
+    size = LayoutSize(m_image->size());
+  }
+
+  if (sizeType == IntrinsicCorrectedToDPR && hasDevicePixelRatioHeaderValue() &&
+      devicePixelRatioHeaderValue() > 0)
+    multiplier = 1 / devicePixelRatioHeaderValue();
+
+  if (multiplier == 1 || m_image->hasRelativeSize())
+    return size;
+
+  // Don't let images that have a width/height >= 1 shrink below 1 when zoomed.
+  LayoutSize minimumSize(
+      size.width() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit(),
+      LayoutUnit(size.height() > LayoutUnit() ? LayoutUnit(1) : LayoutUnit()));
+  size.scale(multiplier);
+  size.clampToMinimumSize(minimumSize);
+  return size;
+}
+
+void ImageResourceContent::notifyObservers(
+    NotifyFinishOption notifyingFinishOption,
+    const IntRect* changeRect) {
+  for (auto* observer : m_finishedObservers.asVector()) {
+    if (m_finishedObservers.contains(observer))
+      observer->imageChanged(this, changeRect);
+  }
+  for (auto* observer : m_observers.asVector()) {
+    if (m_observers.contains(observer)) {
+      observer->imageChanged(this, changeRect);
+      if (notifyingFinishOption == ShouldNotifyFinish &&
+          m_observers.contains(observer) &&
+          !m_info->schedulingReloadOrShouldReloadBrokenPlaceholder()) {
+        markObserverFinished(observer);
+        observer->imageNotifyFinished(this);
+      }
+    }
+  }
+}
+
+PassRefPtr<Image> ImageResourceContent::createImage() {
+  if (m_info->response().mimeType() == "image/svg+xml")
+    return SVGImage::create(this);
+  return BitmapImage::create(this);
+}
+
+void ImageResourceContent::clearImage() {
+  if (!m_image)
+    return;
+  int64_t length = m_image->data() ? m_image->data()->size() : 0;
+  v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-length);
+
+  // If our Image has an observer, it's always us so we need to clear the back
+  // pointer before dropping our reference.
+  m_image->clearImageObserver();
+  m_image.clear();
+  m_sizeAvailable = Image::SizeUnavailable;
+}
+
+void ImageResourceContent::clearImageAndNotifyObservers(
+    NotifyFinishOption notifyingFinishOption) {
+  clearImage();
+  notifyObservers(notifyingFinishOption);
+}
+
+void ImageResourceContent::updateImage(PassRefPtr<SharedBuffer> data,
+                                       ClearImageOption clearImageOption,
+                                       bool allDataReceived) {
+  TRACE_EVENT0("blink", "ImageResourceContent::updateImage");
+
+  if (clearImageOption == ImageResourceContent::ClearExistingImage) {
+    clearImage();
+  }
+
+  // Have the image update its data from its internal buffer. It will not do
+  // anything now, but will delay decoding until queried for info (like size or
+  // specific image frames).
+  if (data) {
+    if (!m_image)
+      m_image = createImage();
+    DCHECK(m_image);
+    m_sizeAvailable = m_image->setData(std::move(data), allDataReceived);
+  }
+
+  // Go ahead and tell our observers to try to draw if we have either received
+  // all the data or the size is known. Each chunk from the network causes
+  // observers to repaint, which will force that chunk to decode.
+  if (m_sizeAvailable == Image::SizeUnavailable && !allDataReceived)
+    return;
+
+  if (m_info->isPlaceholder() && allDataReceived && m_image &&
+      !m_image->isNull()) {
+    if (m_sizeAvailable == Image::SizeAvailable) {
+      // TODO(sclittle): Show the original image if the response consists of the
+      // entire image, such as if the entire image response body is smaller than
+      // the requested range.
+      IntSize dimensions = m_image->size();
+
+      clearImage();
+      m_image = PlaceholderImage::create(this, dimensions);
+    } else {
+      // Clear the image so that it gets treated like a decoding error, since
+      // the attempt to build a placeholder image failed.
+      clearImage();
+    }
+  }
+
+  if (!m_image || m_image->isNull()) {
+    clearImage();
+    m_info->decodeError(allDataReceived);
+  }
+
+  // It would be nice to only redraw the decoded band of the image, but with the
+  // current design (decoding delayed until painting) that seems hard.
+  notifyObservers(allDataReceived ? ShouldNotifyFinish : DoNotNotifyFinish);
+}
+
+void ImageResourceContent::decodedSizeChangedTo(const blink::Image* image,
+                                                size_t newSize) {
+  if (!image || image != m_image)
+    return;
+
+  m_info->setDecodedSize(newSize);
+}
+
+bool ImageResourceContent::shouldPauseAnimation(const blink::Image* image) {
+  if (!image || image != m_image)
+    return false;
+
+  for (const auto& it : m_finishedObservers)
+    if (it.key->willRenderImage())
+      return false;
+
+  for (const auto& it : m_observers)
+    if (it.key->willRenderImage())
+      return false;
+
+  return true;
+}
+
+void ImageResourceContent::animationAdvanced(const blink::Image* image) {
+  if (!image || image != m_image)
+    return;
+  notifyObservers(DoNotNotifyFinish);
+}
+
+void ImageResourceContent::updateImageAnimationPolicy() {
+  if (!m_image)
+    return;
+
+  ImageAnimationPolicy newPolicy = ImageAnimationPolicyAllowed;
+  for (const auto& it : m_finishedObservers) {
+    if (it.key->getImageAnimationPolicy(newPolicy))
+      break;
+  }
+  for (const auto& it : m_observers) {
+    if (it.key->getImageAnimationPolicy(newPolicy))
+      break;
+  }
+
+  if (m_image->animationPolicy() != newPolicy) {
+    m_image->resetAnimation();
+    m_image->setAnimationPolicy(newPolicy);
+  }
+}
+
+void ImageResourceContent::changedInRect(const blink::Image* image,
+                                         const IntRect& rect) {
+  if (!image || image != m_image)
+    return;
+  notifyObservers(DoNotNotifyFinish, &rect);
+}
+
+bool ImageResourceContent::isAccessAllowed(SecurityOrigin* securityOrigin) {
+  return m_info->isAccessAllowed(
+      securityOrigin, getImage()->currentFrameHasSingleSecurityOrigin()
+                          ? ImageResourceInfo::HasSingleSecurityOrigin
+                          : ImageResourceInfo::HasMultipleSecurityOrigin);
+}
+
+void ImageResourceContent::emulateLoadStartedForInspector(
+    ResourceFetcher* fetcher,
+    const KURL& url,
+    const AtomicString& initiatorName) {
+  m_info->emulateLoadStartedForInspector(fetcher, url, initiatorName);
+}
+
+// TODO(hiroshige): Consider removing the following methods, or stoping
+// redirecting to ImageResource.
+bool ImageResourceContent::isLoaded() const {
+  return getStatus() > ResourceStatus::Pending;
+}
+
+bool ImageResourceContent::isLoading() const {
+  return getStatus() == ResourceStatus::Pending;
+}
+
+bool ImageResourceContent::errorOccurred() const {
+  return getStatus() == ResourceStatus::LoadError ||
+         getStatus() == ResourceStatus::DecodeError;
+}
+
+bool ImageResourceContent::loadFailedOrCanceled() const {
+  return getStatus() == ResourceStatus::LoadError;
+}
+
+ResourceStatus ImageResourceContent::getStatus() const {
+  return m_info->getStatus();
+}
+
+const KURL& ImageResourceContent::url() const {
+  return m_info->url();
+}
+
+bool ImageResourceContent::hasCacheControlNoStoreHeader() const {
+  return m_info->hasCacheControlNoStoreHeader();
+}
+
+float ImageResourceContent::devicePixelRatioHeaderValue() const {
+  return m_info->devicePixelRatioHeaderValue();
+}
+
+bool ImageResourceContent::hasDevicePixelRatioHeaderValue() const {
+  return m_info->hasDevicePixelRatioHeaderValue();
+}
+
+const ResourceResponse& ImageResourceContent::response() const {
+  return m_info->response();
+}
+
+const ResourceError& ImageResourceContent::resourceError() const {
+  return m_info->resourceError();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceContent.h b/third_party/WebKit/Source/core/fetch/ImageResourceContent.h
new file mode 100644
index 0000000..8ef0838
--- /dev/null
+++ b/third_party/WebKit/Source/core/fetch/ImageResourceContent.h
@@ -0,0 +1,164 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ImageResourceContent_h
+#define ImageResourceContent_h
+
+#include "core/CoreExport.h"
+#include "core/fetch/ResourceStatus.h"
+#include "platform/geometry/IntRect.h"
+#include "platform/geometry/IntSizeHash.h"
+#include "platform/geometry/LayoutSize.h"
+#include "platform/graphics/Image.h"
+#include "platform/graphics/ImageObserver.h"
+#include "platform/graphics/ImageOrientation.h"
+#include "platform/network/ResourceLoadPriority.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/HashCountedSet.h"
+#include "wtf/HashMap.h"
+#include <memory>
+
+namespace blink {
+
+class FetchRequest;
+class ImageResourceInfo;
+class ImageResourceObserver;
+class ResourceError;
+class ResourceFetcher;
+class ResourceResponse;
+class SecurityOrigin;
+
+// ImageResourceContent is a container that holds fetch result of
+// an ImageResource in a decoded form.
+// Classes that use the fetched images
+// should hold onto this class and/or inherit ImageResourceObserver,
+// instead of holding onto ImageResource or inheriting ResourceClient.
+// https://docs.google.com/document/d/1O-fB83mrE0B_V8gzXNqHgmRLCvstTB4MMi3RnVLr8bE/edit?usp=sharing
+// TODO(hiroshige): Make ImageResourceContent ResourceClient and remove the
+// word 'observer' from ImageResource.
+// TODO(hiroshige): Rename local variables of type ImageResourceContent to
+// e.g. |imageContent|. Currently they have Resource-like names.
+class CORE_EXPORT ImageResourceContent final
+    : public GarbageCollectedFinalized<ImageResourceContent>,
+      public ImageObserver {
+  USING_GARBAGE_COLLECTED_MIXIN(ImageResourceContent);
+
+ public:
+  static ImageResourceContent* create(
+      PassRefPtr<blink::Image> image = nullptr) {
+    return new ImageResourceContent(std::move(image));
+  }
+  static ImageResourceContent* fetch(FetchRequest&, ResourceFetcher*);
+
+  // Returns the nullImage() if the image is not available yet.
+  blink::Image* getImage();
+  bool hasImage() const { return m_image.get(); }
+
+  static std::pair<blink::Image*, float> brokenImage(
+      float deviceScaleFactor);  // Returns an image and the image's resolution
+                                 // scale factor.
+
+  bool usesImageContainerSize() const;
+  bool imageHasRelativeSize() const;
+  // The device pixel ratio we got from the server for this image, or 1.0.
+  float devicePixelRatioHeaderValue() const;
+  bool hasDevicePixelRatioHeaderValue() const;
+
+  enum SizeType {
+    // Report the intrinsic size.
+    IntrinsicSize,
+
+    // Report the intrinsic size corrected to account for image density.
+    IntrinsicCorrectedToDPR,
+  };
+
+  // This method takes a zoom multiplier that can be used to increase the
+  // natural size of the image by the zoom.
+  LayoutSize imageSize(
+      RespectImageOrientationEnum shouldRespectImageOrientation,
+      float multiplier,
+      SizeType = IntrinsicSize);
+
+  void updateImageAnimationPolicy();
+
+  void addObserver(ImageResourceObserver*);
+  void removeObserver(ImageResourceObserver*);
+
+  DECLARE_TRACE();
+
+  // Redirecting methods to Resource.
+  const KURL& url() const;
+  bool isAccessAllowed(SecurityOrigin*);
+  const ResourceResponse& response() const;
+  bool isLoaded() const;
+  bool isLoading() const;
+  bool errorOccurred() const;
+  bool loadFailedOrCanceled() const;
+  ResourceStatus getStatus() const;
+  const ResourceError& resourceError() const;
+
+  // For FrameSerializer.
+  bool hasCacheControlNoStoreHeader() const;
+
+  void emulateLoadStartedForInspector(ResourceFetcher*,
+                                      const KURL&,
+                                      const AtomicString& initiatorName);
+
+  void setNotRefetchableDataFromDiskCache() {
+    m_isRefetchableDataFromDiskCache = false;
+  }
+
+  // For ImageResource only.
+  void setImageResourceInfo(ImageResourceInfo*);
+  enum ClearImageOption { ClearExistingImage, KeepExistingImage };
+  void updateImage(PassRefPtr<SharedBuffer>,
+                   ClearImageOption,
+                   bool allDataReceived);
+  enum NotifyFinishOption { ShouldNotifyFinish, DoNotNotifyFinish };
+  void clearImage();
+  void clearImageAndNotifyObservers(NotifyFinishOption);
+  ResourcePriority priorityFromObservers() const;
+  void destroyDecodedData();
+  void doResetAnimation();
+  PassRefPtr<const SharedBuffer> resourceBuffer() const;
+  bool shouldUpdateImageImmediately() const;
+  bool hasObservers() const {
+    return !m_observers.isEmpty() || !m_finishedObservers.isEmpty();
+  }
+  bool isRefetchableDataFromDiskCache() const {
+    return m_isRefetchableDataFromDiskCache;
+  }
+
+ private:
+  explicit ImageResourceContent(PassRefPtr<blink::Image> = nullptr);
+
+  // ImageObserver
+  void decodedSizeChangedTo(const blink::Image*, size_t newSize) override;
+  bool shouldPauseAnimation(const blink::Image*) override;
+  void animationAdvanced(const blink::Image*) override;
+  void changedInRect(const blink::Image*, const IntRect&) override;
+
+  PassRefPtr<Image> createImage();
+
+  // If not null, changeRect is the changed part of the image.
+  void notifyObservers(NotifyFinishOption, const IntRect* changeRect = nullptr);
+  void markObserverFinished(ImageResourceObserver*);
+
+  Member<ImageResourceInfo> m_info;
+
+  RefPtr<blink::Image> m_image;
+
+  HashCountedSet<ImageResourceObserver*> m_observers;
+  HashCountedSet<ImageResourceObserver*> m_finishedObservers;
+
+  Image::SizeAvailability m_sizeAvailable = Image::SizeUnavailable;
+
+  // Indicates if this resource's encoded image data can be purged and refetched
+  // from disk cache to save memory usage. See crbug/664437.
+  bool m_isRefetchableDataFromDiskCache;
+};
+
+}  // namespace blink
+
+#endif
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceInfo.h b/third_party/WebKit/Source/core/fetch/ImageResourceInfo.h
new file mode 100644
index 0000000..70f787b
--- /dev/null
+++ b/third_party/WebKit/Source/core/fetch/ImageResourceInfo.h
@@ -0,0 +1,71 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ImageResourceInfo_h
+#define ImageResourceInfo_h
+
+#include "core/CoreExport.h"
+#include "core/fetch/ResourceStatus.h"
+#include "platform/heap/Handle.h"
+#include "platform/heap/Heap.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/Forward.h"
+
+namespace blink {
+
+class ResourceError;
+class ResourceFetcher;
+class ResourceResponse;
+class SecurityOrigin;
+
+// Delegate class of ImageResource that encapsulates the interface and data
+// visible to ImageResourceContent.
+// Do not add new members or new call sites unless really needed.
+// TODO(hiroshige): reduce the members of this class to further decouple
+// ImageResource and ImageResourceContent.
+class CORE_EXPORT ImageResourceInfo : public GarbageCollectedMixin {
+ public:
+  ~ImageResourceInfo() {}
+  virtual const KURL& url() const = 0;
+  virtual bool isSchedulingReload() const = 0;
+  virtual bool hasDevicePixelRatioHeaderValue() const = 0;
+  virtual float devicePixelRatioHeaderValue() const = 0;
+  virtual const ResourceResponse& response() const = 0;
+  virtual ResourceStatus getStatus() const = 0;
+  virtual bool isPlaceholder() const = 0;
+  virtual bool isCacheValidator() const = 0;
+  virtual bool schedulingReloadOrShouldReloadBrokenPlaceholder() const = 0;
+  enum DoesCurrentFrameHaveSingleSecurityOrigin {
+    HasMultipleSecurityOrigin,
+    HasSingleSecurityOrigin
+  };
+  virtual bool isAccessAllowed(
+      SecurityOrigin*,
+      DoesCurrentFrameHaveSingleSecurityOrigin) const = 0;
+  virtual bool hasCacheControlNoStoreHeader() const = 0;
+  virtual const ResourceError& resourceError() const = 0;
+
+  // Like Resource::error(), decodeError() makes corresponding ImageResource
+  // (if any) DecodeError and finishes loading.
+  virtual void decodeError(bool allDataReceived) = 0;
+
+  // TODO(hiroshige): Remove this once MemoryCache becomes further weaker.
+  virtual void setDecodedSize(size_t) = 0;
+
+  // TODO(hiroshige): Remove these.
+  virtual void willAddClientOrObserver() = 0;
+  virtual void didRemoveClientOrObserver() = 0;
+
+  // TODO(hiroshige): Remove this. crbug.com/666214
+  virtual void emulateLoadStartedForInspector(
+      ResourceFetcher*,
+      const KURL&,
+      const AtomicString& initiatorName) = 0;
+
+  DEFINE_INLINE_VIRTUAL_TRACE() {}
+};
+
+}  // namespace blink
+
+#endif
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceObserver.h b/third_party/WebKit/Source/core/fetch/ImageResourceObserver.h
index e70f18c..7a6922f 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResourceObserver.h
+++ b/third_party/WebKit/Source/core/fetch/ImageResourceObserver.h
@@ -30,7 +30,7 @@
 
 namespace blink {
 
-class ImageResource;
+class ImageResourceContent;
 class IntRect;
 
 class CORE_EXPORT ImageResourceObserver {
@@ -40,11 +40,11 @@
   // Called whenever a frame of an image changes, either because we got more
   // data from the network or because we are animating. If not null, the IntRect
   // is the changed rect of the image.
-  virtual void imageChanged(ImageResource*, const IntRect* = 0) {}
+  virtual void imageChanged(ImageResourceContent*, const IntRect* = 0) {}
 
   // Called just after imageChanged() if all image data is received or errored.
   // TODO(hiroshige): Merge imageNotifyFinished() into imageChanged().
-  virtual void imageNotifyFinished(ImageResource*) {}
+  virtual void imageNotifyFinished(ImageResourceContent*) {}
 
   // Called to find out if this client wants to actually display the image. Used
   // to tell when we can halt animation. Content nodes that hold image refs for
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp b/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
index 6c332ef4..7a89810 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
@@ -242,7 +242,7 @@
   cachedImage->loader()->didReceiveResponse(
       WrappedResourceResponse(multipartResponse), nullptr);
   EXPECT_FALSE(cachedImage->resourceBuffer());
-  EXPECT_FALSE(cachedImage->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->hasImage());
   EXPECT_EQ(0, client->imageChangedCount());
   EXPECT_FALSE(client->notifyFinishedCalled());
   EXPECT_EQ("multipart/x-mixed-replace", cachedImage->response().mimeType());
@@ -254,7 +254,7 @@
   // Send the response for the first real part. No image or data buffer is
   // created.
   EXPECT_FALSE(cachedImage->resourceBuffer());
-  EXPECT_FALSE(cachedImage->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->hasImage());
   EXPECT_EQ(0, client->imageChangedCount());
   EXPECT_FALSE(client->notifyFinishedCalled());
   EXPECT_EQ("image/svg+xml", cachedImage->response().mimeType());
@@ -266,7 +266,7 @@
   // created.
   cachedImage->appendData(secondPart, strlen(secondPart));
   EXPECT_TRUE(cachedImage->resourceBuffer());
-  EXPECT_FALSE(cachedImage->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->hasImage());
   EXPECT_EQ(0, client->imageChangedCount());
   EXPECT_FALSE(client->notifyFinishedCalled());
 
@@ -287,10 +287,10 @@
   cachedImage->loader()->didFinishLoading(0.0, 0, 0);
   EXPECT_TRUE(cachedImage->resourceBuffer());
   EXPECT_FALSE(cachedImage->errorOccurred());
-  ASSERT_TRUE(cachedImage->hasImage());
-  EXPECT_FALSE(cachedImage->getImage()->isNull());
-  EXPECT_EQ(1, cachedImage->getImage()->width());
-  EXPECT_EQ(1, cachedImage->getImage()->height());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
+  EXPECT_EQ(1, cachedImage->getContent()->getImage()->width());
+  EXPECT_EQ(1, cachedImage->getContent()->getImage()->height());
   EXPECT_EQ(1, client->imageChangedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
   EXPECT_EQ(1, client2->imageChangedCount());
@@ -351,23 +351,23 @@
   cachedImage->finish();
   EXPECT_EQ(0u, cachedImage->encodedSizeMemoryUsageForTesting());
   EXPECT_FALSE(cachedImage->errorOccurred());
-  ASSERT_TRUE(cachedImage->hasImage());
-  EXPECT_FALSE(cachedImage->getImage()->isNull());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
   EXPECT_TRUE(client->notifyFinishedCalled());
 
   // The prune comes when the ImageResource still has clients. The image should
   // not be deleted.
   cachedImage->prune();
   EXPECT_TRUE(cachedImage->isAlive());
-  ASSERT_TRUE(cachedImage->hasImage());
-  EXPECT_FALSE(cachedImage->getImage()->isNull());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
 
   // The ImageResource no longer has clients. The decoded image data should be
   // deleted by prune.
   client->removeAsClient();
   cachedImage->prune();
   EXPECT_FALSE(cachedImage->isAlive());
-  EXPECT_TRUE(cachedImage->hasImage());
+  EXPECT_TRUE(cachedImage->getContent()->hasImage());
   // TODO(hajimehoshi): Should check cachedImage doesn't have decoded image
   // data.
 }
@@ -388,11 +388,11 @@
                           sizeof(kJpegImage));
   cachedImage->finish();
   EXPECT_FALSE(cachedImage->errorOccurred());
-  ASSERT_TRUE(cachedImage->hasImage());
-  EXPECT_FALSE(cachedImage->getImage()->isNull());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
   EXPECT_EQ(2, client->imageChangedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_TRUE(cachedImage->getImage()->isBitmapImage());
+  EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
 }
 
 TEST(ImageResourceTest, ReloadIfLoFiOrPlaceholderAfterFinished) {
@@ -419,8 +419,8 @@
                           sizeof(kJpegImage));
   cachedImage->finish();
   EXPECT_FALSE(cachedImage->errorOccurred());
-  ASSERT_TRUE(cachedImage->hasImage());
-  EXPECT_FALSE(cachedImage->getImage()->isNull());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
   EXPECT_EQ(2, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnLastImageChanged());
@@ -428,15 +428,15 @@
   EXPECT_TRUE(client->notifyFinishedCalled());
   EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnNotifyFinished());
   EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnImageNotifyFinished());
-  EXPECT_TRUE(cachedImage->getImage()->isBitmapImage());
-  EXPECT_EQ(1, cachedImage->getImage()->width());
-  EXPECT_EQ(1, cachedImage->getImage()->height());
+  EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(1, cachedImage->getContent()->getImage()->width());
+  EXPECT_EQ(1, cachedImage->getContent()->getImage()->height());
 
   // Call reloadIfLoFiOrPlaceholder() after the image has finished loading.
   cachedImage->reloadIfLoFiOrPlaceholder(fetcher);
   EXPECT_FALSE(cachedImage->errorOccurred());
   EXPECT_FALSE(cachedImage->resourceBuffer());
-  EXPECT_FALSE(cachedImage->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->hasImage());
   EXPECT_EQ(3, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
 
@@ -447,8 +447,8 @@
   cachedImage->loader()->didFinishLoading(0.0, sizeof(kJpegImage2),
                                           sizeof(kJpegImage2));
   EXPECT_FALSE(cachedImage->errorOccurred());
-  ASSERT_TRUE(cachedImage->hasImage());
-  EXPECT_FALSE(cachedImage->getImage()->isNull());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
   EXPECT_EQ(sizeof(kJpegImage2), client->encodedSizeOnLastImageChanged());
   EXPECT_TRUE(client->notifyFinishedCalled());
 
@@ -456,9 +456,9 @@
   EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnNotifyFinished());
   EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnImageNotifyFinished());
 
-  EXPECT_TRUE(cachedImage->getImage()->isBitmapImage());
-  EXPECT_EQ(50, cachedImage->getImage()->width());
-  EXPECT_EQ(50, cachedImage->getImage()->height());
+  EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(50, cachedImage->getContent()->getImage()->width());
+  EXPECT_EQ(50, cachedImage->getContent()->getImage()->height());
 }
 
 TEST(ImageResourceTest, ReloadIfLoFiOrPlaceholderDuringFetch) {
@@ -486,20 +486,20 @@
       reinterpret_cast<const char*>(kJpegImage), sizeof(kJpegImage));
 
   EXPECT_FALSE(cachedImage->errorOccurred());
-  ASSERT_TRUE(cachedImage->hasImage());
-  EXPECT_FALSE(cachedImage->getImage()->isNull());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
   EXPECT_EQ(1, client->imageChangedCount());
   EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnLastImageChanged());
   EXPECT_FALSE(client->notifyFinishedCalled());
-  EXPECT_TRUE(cachedImage->getImage()->isBitmapImage());
-  EXPECT_EQ(1, cachedImage->getImage()->width());
-  EXPECT_EQ(1, cachedImage->getImage()->height());
+  EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(1, cachedImage->getContent()->getImage()->width());
+  EXPECT_EQ(1, cachedImage->getContent()->getImage()->height());
 
   // Call reloadIfLoFiOrPlaceholder() while the image is still loading.
   cachedImage->reloadIfLoFiOrPlaceholder(fetcher);
   EXPECT_FALSE(cachedImage->errorOccurred());
   EXPECT_FALSE(cachedImage->resourceBuffer());
-  EXPECT_FALSE(cachedImage->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->hasImage());
   EXPECT_EQ(2, client->imageChangedCount());
   EXPECT_EQ(0U, client->encodedSizeOnLastImageChanged());
   // The client should not have been notified of completion yet, since the image
@@ -516,17 +516,17 @@
                                           sizeof(kJpegImage2));
 
   EXPECT_FALSE(cachedImage->errorOccurred());
-  ASSERT_TRUE(cachedImage->hasImage());
-  EXPECT_FALSE(cachedImage->getImage()->isNull());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
   EXPECT_EQ(sizeof(kJpegImage2), client->encodedSizeOnLastImageChanged());
   // The client should have been notified of completion only after the reload
   // completed.
   EXPECT_TRUE(client->notifyFinishedCalled());
   EXPECT_EQ(sizeof(kJpegImage2), client->encodedSizeOnNotifyFinished());
   EXPECT_EQ(sizeof(kJpegImage2), client->encodedSizeOnImageNotifyFinished());
-  EXPECT_TRUE(cachedImage->getImage()->isBitmapImage());
-  EXPECT_EQ(50, cachedImage->getImage()->width());
-  EXPECT_EQ(50, cachedImage->getImage()->height());
+  EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(50, cachedImage->getContent()->getImage()->width());
+  EXPECT_EQ(50, cachedImage->getContent()->getImage()->height());
 }
 
 TEST(ImageResourceTest, ReloadIfLoFiOrPlaceholderForPlaceholder) {
@@ -581,11 +581,11 @@
                   strlen(kSvgImage));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(1, client->imageChangedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_FALSE(imageResource->getImage()->isBitmapImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
 }
 
 TEST(ImageResourceTest, SuccessfulRevalidationJpeg) {
@@ -599,14 +599,14 @@
                   sizeof(kJpegImage));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(2, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_TRUE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(1, imageResource->getImage()->width());
-  EXPECT_EQ(1, imageResource->getImage()->height());
+  EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
 
   imageResource->setRevalidatingRequest(ResourceRequest(url));
   ResourceResponse response;
@@ -616,14 +616,14 @@
   imageResource->responseReceived(response, nullptr);
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(2, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_TRUE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(1, imageResource->getImage()->width());
-  EXPECT_EQ(1, imageResource->getImage()->height());
+  EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
 }
 
 TEST(ImageResourceTest, SuccessfulRevalidationSvg) {
@@ -636,14 +636,14 @@
                   strlen(kSvgImage));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(1, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_FALSE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(200, imageResource->getImage()->width());
-  EXPECT_EQ(200, imageResource->getImage()->height());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(200, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(200, imageResource->getContent()->getImage()->height());
 
   imageResource->setRevalidatingRequest(ResourceRequest(url));
   ResourceResponse response;
@@ -652,14 +652,14 @@
   imageResource->responseReceived(response, nullptr);
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(1, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_FALSE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(200, imageResource->getImage()->width());
-  EXPECT_EQ(200, imageResource->getImage()->height());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(200, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(200, imageResource->getContent()->getImage()->height());
 }
 
 TEST(ImageResourceTest, FailedRevalidationJpegToJpeg) {
@@ -673,14 +673,14 @@
                   sizeof(kJpegImage));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(2, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_TRUE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(1, imageResource->getImage()->width());
-  EXPECT_EQ(1, imageResource->getImage()->height());
+  EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
 
   imageResource->setRevalidatingRequest(ResourceRequest(url));
   receiveResponse(imageResource, url, "image/jpeg",
@@ -688,14 +688,14 @@
                   sizeof(kJpegImage2));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(4, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_TRUE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(50, imageResource->getImage()->width());
-  EXPECT_EQ(50, imageResource->getImage()->height());
+  EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(50, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(50, imageResource->getContent()->getImage()->height());
 }
 
 TEST(ImageResourceTest, FailedRevalidationJpegToSvg) {
@@ -709,28 +709,28 @@
                   sizeof(kJpegImage));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(2, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_TRUE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(1, imageResource->getImage()->width());
-  EXPECT_EQ(1, imageResource->getImage()->height());
+  EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
 
   imageResource->setRevalidatingRequest(ResourceRequest(url));
   receiveResponse(imageResource, url, "image/svg+xml", kSvgImage,
                   strlen(kSvgImage));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(3, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_FALSE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(200, imageResource->getImage()->width());
-  EXPECT_EQ(200, imageResource->getImage()->height());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(200, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(200, imageResource->getContent()->getImage()->height());
 }
 
 TEST(ImageResourceTest, FailedRevalidationSvgToJpeg) {
@@ -743,14 +743,14 @@
                   strlen(kSvgImage));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(1, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_FALSE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(200, imageResource->getImage()->width());
-  EXPECT_EQ(200, imageResource->getImage()->height());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(200, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(200, imageResource->getContent()->getImage()->height());
 
   imageResource->setRevalidatingRequest(ResourceRequest(url));
   receiveResponse(imageResource, url, "image/jpeg",
@@ -758,14 +758,14 @@
                   sizeof(kJpegImage));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(3, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_TRUE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(1, imageResource->getImage()->width());
-  EXPECT_EQ(1, imageResource->getImage()->height());
+  EXPECT_TRUE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
 }
 
 TEST(ImageResourceTest, FailedRevalidationSvgToSvg) {
@@ -778,28 +778,28 @@
                   strlen(kSvgImage));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(1, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_FALSE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(200, imageResource->getImage()->width());
-  EXPECT_EQ(200, imageResource->getImage()->height());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(200, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(200, imageResource->getContent()->getImage()->height());
 
   imageResource->setRevalidatingRequest(ResourceRequest(url));
   receiveResponse(imageResource, url, "image/svg+xml", kSvgImage2,
                   strlen(kSvgImage2));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
   EXPECT_EQ(2, client->imageChangedCount());
   EXPECT_EQ(1, client->imageNotifyFinishedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_FALSE(imageResource->getImage()->isBitmapImage());
-  EXPECT_EQ(300, imageResource->getImage()->width());
-  EXPECT_EQ(300, imageResource->getImage()->height());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(300, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(300, imageResource->getContent()->getImage()->height());
 }
 
 // Tests for pruning.
@@ -817,10 +817,10 @@
                   sizeof(kJpegImage));
 
   EXPECT_FALSE(imageResource->errorOccurred());
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
-  EXPECT_EQ(1, imageResource->getImage()->width());
-  EXPECT_EQ(1, imageResource->getImage()->height());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
   EXPECT_TRUE(client1->notifyFinishedCalled());
 
   client1->removeAsClient();
@@ -829,16 +829,16 @@
 
   imageResource->prune();
 
-  EXPECT_TRUE(imageResource->hasImage());
+  EXPECT_TRUE(imageResource->getContent()->hasImage());
 
   // Re-adds a ResourceClient but not ImageResourceObserver.
   Persistent<MockResourceClient> client2 =
       new MockResourceClient(imageResource);
 
-  ASSERT_TRUE(imageResource->hasImage());
-  EXPECT_FALSE(imageResource->getImage()->isNull());
-  EXPECT_EQ(1, imageResource->getImage()->width());
-  EXPECT_EQ(1, imageResource->getImage()->height());
+  ASSERT_TRUE(imageResource->getContent()->hasImage());
+  EXPECT_FALSE(imageResource->getContent()->getImage()->isNull());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->width());
+  EXPECT_EQ(1, imageResource->getContent()->getImage()->height());
   EXPECT_TRUE(client2->notifyFinishedCalled());
 }
 
@@ -892,10 +892,10 @@
   EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnNotifyFinished());
   EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnImageNotifyFinished());
 
-  ASSERT_TRUE(image->hasImage());
-  EXPECT_EQ(1, image->getImage()->width());
-  EXPECT_EQ(1, image->getImage()->height());
-  EXPECT_TRUE(image->getImage()->isBitmapImage());
+  ASSERT_TRUE(image->getContent()->hasImage());
+  EXPECT_EQ(1, image->getContent()->getImage()->width());
+  EXPECT_EQ(1, image->getContent()->getImage()->height());
+  EXPECT_TRUE(image->getContent()->getImage()->isBitmapImage());
 }
 
 TEST(ImageResourceTest, FetchAllowPlaceholderDataURL) {
@@ -991,11 +991,11 @@
   EXPECT_EQ(kJpegImageSubrangeWithDimensionsLength,
             client->encodedSizeOnImageNotifyFinished());
 
-  ASSERT_TRUE(image->hasImage());
-  EXPECT_EQ(1, image->getImage()->width());
-  EXPECT_EQ(1, image->getImage()->height());
-  EXPECT_FALSE(image->getImage()->isBitmapImage());
-  EXPECT_FALSE(image->getImage()->isSVGImage());
+  ASSERT_TRUE(image->getContent()->hasImage());
+  EXPECT_EQ(1, image->getContent()->getImage()->width());
+  EXPECT_EQ(1, image->getContent()->getImage()->height());
+  EXPECT_FALSE(image->getContent()->getImage()->isBitmapImage());
+  EXPECT_FALSE(image->getContent()->getImage()->isSVGImage());
 }
 
 TEST(ImageResourceTest, FetchAllowPlaceholderUnsuccessful) {
@@ -1049,10 +1049,10 @@
   EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnNotifyFinished());
   EXPECT_EQ(sizeof(kJpegImage), client->encodedSizeOnImageNotifyFinished());
 
-  ASSERT_TRUE(image->hasImage());
-  EXPECT_EQ(1, image->getImage()->width());
-  EXPECT_EQ(1, image->getImage()->height());
-  EXPECT_TRUE(image->getImage()->isBitmapImage());
+  ASSERT_TRUE(image->getContent()->hasImage());
+  EXPECT_EQ(1, image->getContent()->getImage()->width());
+  EXPECT_EQ(1, image->getContent()->getImage()->height());
+  EXPECT_TRUE(image->getContent()->getImage()->isBitmapImage());
 }
 
 TEST(ImageResourceTest, FetchAllowPlaceholderThenDisallowPlaceholder) {
@@ -1154,7 +1154,7 @@
   size_t bytesSent = meaningfulImageSize;
 
   EXPECT_FALSE(cachedImage->errorOccurred());
-  EXPECT_TRUE(cachedImage->hasImage());
+  EXPECT_TRUE(cachedImage->getContent()->hasImage());
   EXPECT_EQ(1, client->imageChangedCount());
 
   platform.runForPeriodSeconds(1.);
@@ -1163,7 +1163,7 @@
   // Sanity check that we created an image after appending |meaningfulImageSize|
   // bytes just once.
   EXPECT_FALSE(cachedImage->errorOccurred());
-  ASSERT_TRUE(cachedImage->hasImage());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
   EXPECT_EQ(1, client->imageChangedCount());
 
   for (int flushCount = 1; flushCount <= 3; ++flushCount) {
@@ -1178,7 +1178,7 @@
           reinterpret_cast<const char*>(kJpegImage2) + bytesSent, 1);
 
       EXPECT_FALSE(cachedImage->errorOccurred());
-      ASSERT_TRUE(cachedImage->hasImage());
+      ASSERT_TRUE(cachedImage->getContent()->hasImage());
       EXPECT_EQ(flushCount, client->imageChangedCount());
 
       ++bytesSent;
@@ -1190,8 +1190,8 @@
   platform.runForPeriodSeconds(10.);
   platform.advanceClockSeconds(10.);
   EXPECT_FALSE(cachedImage->errorOccurred());
-  ASSERT_TRUE(cachedImage->hasImage());
-  EXPECT_FALSE(cachedImage->getImage()->isNull());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
   EXPECT_EQ(4, client->imageChangedCount());
 
   // Append the rest of the data and finish (which causes another flush).
@@ -1201,13 +1201,13 @@
   cachedImage->finish();
 
   EXPECT_FALSE(cachedImage->errorOccurred());
-  ASSERT_TRUE(cachedImage->hasImage());
-  EXPECT_FALSE(cachedImage->getImage()->isNull());
+  ASSERT_TRUE(cachedImage->getContent()->hasImage());
+  EXPECT_FALSE(cachedImage->getContent()->getImage()->isNull());
   EXPECT_EQ(5, client->imageChangedCount());
   EXPECT_TRUE(client->notifyFinishedCalled());
-  EXPECT_TRUE(cachedImage->getImage()->isBitmapImage());
-  EXPECT_EQ(50, cachedImage->getImage()->width());
-  EXPECT_EQ(50, cachedImage->getImage()->height());
+  EXPECT_TRUE(cachedImage->getContent()->getImage()->isBitmapImage());
+  EXPECT_EQ(50, cachedImage->getContent()->getImage()->width());
+  EXPECT_EQ(50, cachedImage->getContent()->getImage()->height());
 
   WTF::setTimeFunctionsForTesting(nullptr);
 }
diff --git a/third_party/WebKit/Source/core/fetch/MockResourceClients.cpp b/third_party/WebKit/Source/core/fetch/MockResourceClients.cpp
index 88a831e9..8c8c861 100644
--- a/third_party/WebKit/Source/core/fetch/MockResourceClients.cpp
+++ b/third_party/WebKit/Source/core/fetch/MockResourceClients.cpp
@@ -5,6 +5,7 @@
 #include "core/fetch/MockResourceClients.h"
 
 #include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
@@ -48,32 +49,32 @@
       m_encodedSizeOnLastImageChanged(0),
       m_imageNotifyFinishedCount(0),
       m_encodedSizeOnImageNotifyFinished(0) {
-  toImageResource(m_resource.get())->addObserver(this);
+  toImageResource(m_resource)->getContent()->addObserver(this);
 }
 
 MockImageResourceClient::~MockImageResourceClient() {}
 
 void MockImageResourceClient::removeAsClient() {
-  toImageResource(m_resource.get())->removeObserver(this);
+  toImageResource(m_resource)->getContent()->removeObserver(this);
   MockResourceClient::removeAsClient();
 }
 
 void MockImageResourceClient::dispose() {
   if (m_resource)
-    toImageResource(m_resource.get())->removeObserver(this);
+    toImageResource(m_resource)->getContent()->removeObserver(this);
   MockResourceClient::dispose();
 }
 
-void MockImageResourceClient::imageChanged(ImageResource* image,
+void MockImageResourceClient::imageChanged(ImageResourceContent* image,
                                            const IntRect*) {
   m_imageChangedCount++;
-  m_encodedSizeOnLastImageChanged = image->encodedSize();
+  m_encodedSizeOnLastImageChanged = m_resource->encodedSize();
 }
 
-void MockImageResourceClient::imageNotifyFinished(ImageResource* image) {
+void MockImageResourceClient::imageNotifyFinished(ImageResourceContent* image) {
   ASSERT_EQ(0, m_imageNotifyFinishedCount);
   m_imageNotifyFinishedCount++;
-  m_encodedSizeOnImageNotifyFinished = image->encodedSize();
+  m_encodedSizeOnImageNotifyFinished = m_resource->encodedSize();
 }
 
 bool MockImageResourceClient::notifyFinishedCalled() const {
diff --git a/third_party/WebKit/Source/core/fetch/MockResourceClients.h b/third_party/WebKit/Source/core/fetch/MockResourceClients.h
index 0f911d4..90fe127 100644
--- a/third_party/WebKit/Source/core/fetch/MockResourceClients.h
+++ b/third_party/WebKit/Source/core/fetch/MockResourceClients.h
@@ -31,6 +31,8 @@
 #ifndef MockResourceClients_h
 #define MockResourceClients_h
 
+#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ImageResourceObserver.h"
 #include "core/fetch/Resource.h"
 #include "core/fetch/ResourceClient.h"
@@ -72,8 +74,8 @@
   explicit MockImageResourceClient(ImageResource*);
   ~MockImageResourceClient() override;
 
-  void imageNotifyFinished(ImageResource*) override;
-  void imageChanged(ImageResource*, const IntRect*) override;
+  void imageNotifyFinished(ImageResourceContent*) override;
+  void imageChanged(ImageResourceContent*, const IntRect*) override;
 
   String debugName() const override { return "MockImageResourceClient"; }
 
diff --git a/third_party/WebKit/Source/core/frame/FrameSerializer.cpp b/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
index d1d4ed2..d3e0963 100644
--- a/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
@@ -47,7 +47,7 @@
 #include "core/dom/Element.h"
 #include "core/dom/Text.h"
 #include "core/editing/serializers/MarkupAccumulator.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/HTMLImageElement.h"
@@ -318,14 +318,14 @@
       HTMLImageElement& imageElement = toHTMLImageElement(element);
       KURL url =
           document.completeURL(imageElement.getAttribute(HTMLNames::srcAttr));
-      ImageResource* cachedImage = imageElement.cachedImage();
+      ImageResourceContent* cachedImage = imageElement.cachedImage();
       addImageToResources(cachedImage, url);
     } else if (isHTMLInputElement(element)) {
       HTMLInputElement& inputElement = toHTMLInputElement(element);
       if (inputElement.type() == InputTypeNames::image &&
           inputElement.imageLoader()) {
         KURL url = inputElement.src();
-        ImageResource* cachedImage = inputElement.imageLoader()->image();
+        ImageResourceContent* cachedImage = inputElement.imageLoader()->image();
         addImageToResources(cachedImage, url);
       }
     } else if (isHTMLLinkElement(element)) {
@@ -459,10 +459,12 @@
          !url.protocolIsData() && !m_delegate.shouldSkipResourceWithURL(url);
 }
 
-void FrameSerializer::addToResources(const Resource& resource,
-                                     PassRefPtr<const SharedBuffer> data,
-                                     const KURL& url) {
-  if (m_delegate.shouldSkipResource(resource))
+void FrameSerializer::addToResources(
+    const String& mimeType,
+    ResourceHasCacheControlNoStoreHeader hasCacheControlNoStoreHeader,
+    PassRefPtr<const SharedBuffer> data,
+    const KURL& url) {
+  if (m_delegate.shouldSkipResource(hasCacheControlNoStoreHeader))
     return;
 
   if (!data) {
@@ -470,12 +472,11 @@
     return;
   }
 
-  String mimeType = resource.response().mimeType();
   m_resources->append(SerializedResource(url, mimeType, std::move(data)));
   m_resourceURLs.add(url);
 }
 
-void FrameSerializer::addImageToResources(ImageResource* image,
+void FrameSerializer::addImageToResources(ImageResourceContent* image,
                                           const KURL& url) {
   if (!image || !image->hasImage() || image->errorOccurred() ||
       !shouldAddURL(url))
@@ -486,7 +487,11 @@
   double imageStartTime = monotonicallyIncreasingTime();
 
   RefPtr<const SharedBuffer> data = image->getImage()->data();
-  addToResources(*image, data, url);
+  addToResources(image->response().mimeType(),
+                 image->hasCacheControlNoStoreHeader()
+                     ? HasCacheControlNoStoreHeader
+                     : NoCacheControlNoStoreHeader,
+                 data, url);
 
   // If we're already reporting time for CSS serialization don't report it for
   // this image to avoid reporting the same time twice.
@@ -507,7 +512,11 @@
 
   RefPtr<const SharedBuffer> data(font->resourceBuffer());
 
-  addToResources(*font, data, font->url());
+  addToResources(font->response().mimeType(),
+                 font->hasCacheControlNoStoreHeader()
+                     ? HasCacheControlNoStoreHeader
+                     : NoCacheControlNoStoreHeader,
+                 data, font->url());
 }
 
 void FrameSerializer::retrieveResourcesForProperties(
diff --git a/third_party/WebKit/Source/core/frame/FrameSerializer.h b/third_party/WebKit/Source/core/frame/FrameSerializer.h
index 199b8c0..42d2681 100644
--- a/third_party/WebKit/Source/core/frame/FrameSerializer.h
+++ b/third_party/WebKit/Source/core/frame/FrameSerializer.h
@@ -48,9 +48,8 @@
 class Document;
 class Element;
 class FontResource;
-class ImageResource;
+class ImageResourceContent;
 class LocalFrame;
-class Resource;
 class SharedBuffer;
 class StylePropertySet;
 
@@ -63,6 +62,11 @@
   STACK_ALLOCATED();
 
  public:
+  enum ResourceHasCacheControlNoStoreHeader {
+    NoCacheControlNoStoreHeader,
+    HasCacheControlNoStoreHeader
+  };
+
   class Delegate {
    public:
     // Controls whether HTML serialization should skip the given attribute.
@@ -88,7 +92,9 @@
     virtual bool shouldSkipResourceWithURL(const KURL&) { return false; }
 
     // Tells whether to skip serialization of a subresource.
-    virtual bool shouldSkipResource(const Resource&) { return false; }
+    virtual bool shouldSkipResource(ResourceHasCacheControlNoStoreHeader) {
+      return false;
+    }
 
     // Returns custom attributes that need to add in order to serialize the
     // element.
@@ -123,10 +129,11 @@
 
   bool shouldAddURL(const KURL&);
 
-  void addToResources(const Resource&,
+  void addToResources(const String& mimeType,
+                      ResourceHasCacheControlNoStoreHeader,
                       PassRefPtr<const SharedBuffer>,
                       const KURL&);
-  void addImageToResources(ImageResource*, const KURL&);
+  void addImageToResources(ImageResourceContent*, const KURL&);
   void addFontToResources(FontResource*);
 
   void retrieveResourcesForProperties(const StylePropertySet*, Document&);
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
index 1e9a96f..4fb11fb 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
@@ -32,7 +32,7 @@
 
 #include "SkPixelRef.h"  // FIXME: qualify this skia header file.
 #include "core/dom/Document.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLImageElement.h"
@@ -81,8 +81,8 @@
   const ImageBitmapOptions defaultOptions;
   HTMLImageElement* imageElement =
       HTMLImageElement::create(*Document::create());
-  ImageResource* image =
-      ImageResource::create(StaticBitmapImage::create(m_image).get());
+  ImageResourceContent* image =
+      ImageResourceContent::create(StaticBitmapImage::create(m_image).get());
   imageElement->setImageResource(image);
 
   Optional<IntRect> cropRect =
@@ -126,8 +126,8 @@
 // reference to the original Image if the HTMLImageElement src is changed.
 TEST_F(ImageBitmapTest, ImageBitmapSourceChanged) {
   HTMLImageElement* image = HTMLImageElement::create(*Document::create());
-  ImageResource* originalImageResource =
-      ImageResource::create(StaticBitmapImage::create(m_image).get());
+  ImageResourceContent* originalImageResource =
+      ImageResourceContent::create(StaticBitmapImage::create(m_image).get());
   image->setImageResource(originalImageResource);
 
   const ImageBitmapOptions defaultOptions;
@@ -140,8 +140,8 @@
             originalImageResource->getImage()->imageForCurrentFrame(
                 ColorBehavior::transformToTargetForTesting()));
 
-  ImageResource* newImageResource =
-      ImageResource::create(StaticBitmapImage::create(m_image2).get());
+  ImageResourceContent* newImageResource =
+      ImageResourceContent::create(StaticBitmapImage::create(m_image2).get());
   image->setImageResource(newImageResource);
 
   // The ImageBitmap should contain the same data as the original cached image
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index 0e17679..2bfb37d 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -33,7 +33,7 @@
 #include "core/dom/Attribute.h"
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/shadow/ShadowRoot.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/Deprecation.h"
 #include "core/frame/ImageBitmap.h"
 #include "core/frame/LocalDOMWindow.h"
@@ -372,9 +372,9 @@
     if (m_isFallbackImage) {
       float deviceScaleFactor = blink::deviceScaleFactor(layoutImage->frame());
       std::pair<Image*, float> brokenImageAndImageScaleFactor =
-          ImageResource::brokenImage(deviceScaleFactor);
-      ImageResource* newImageResource =
-          ImageResource::create(brokenImageAndImageScaleFactor.first);
+          ImageResourceContent::brokenImage(deviceScaleFactor);
+      ImageResourceContent* newImageResource =
+          ImageResourceContent::create(brokenImageAndImageScaleFactor.first);
       layoutImage->imageResource()->setImageResource(newImageResource);
     }
     if (layoutImageResource->hasImage())
@@ -493,7 +493,7 @@
       .image()
       ->imageSize(LayoutObject::shouldRespectImageOrientation(layoutObject()),
                   m_imageDevicePixelRatio,
-                  ImageResource::IntrinsicCorrectedToDPR)
+                  ImageResourceContent::IntrinsicCorrectedToDPR)
       .width()
       .toUnsigned();
 }
@@ -506,7 +506,7 @@
       .image()
       ->imageSize(LayoutObject::shouldRespectImageOrientation(layoutObject()),
                   m_imageDevicePixelRatio,
-                  ImageResource::IntrinsicCorrectedToDPR)
+                  ImageResourceContent::IntrinsicCorrectedToDPR)
       .height()
       .toUnsigned();
 }
@@ -660,7 +660,7 @@
 
 bool HTMLImageElement::wouldTaintOrigin(
     SecurityOrigin* destinationSecurityOrigin) const {
-  ImageResource* image = cachedImage();
+  ImageResourceContent* image = cachedImage();
   if (!image)
     return false;
   return !image->isAccessAllowed(destinationSecurityOrigin);
@@ -668,7 +668,7 @@
 
 FloatSize HTMLImageElement::elementSize(
     const FloatSize& defaultObjectSize) const {
-  ImageResource* image = cachedImage();
+  ImageResourceContent* image = cachedImage();
   if (!image)
     return FloatSize();
 
@@ -682,7 +682,7 @@
 
 FloatSize HTMLImageElement::defaultDestinationSize(
     const FloatSize& defaultObjectSize) const {
-  ImageResource* image = cachedImage();
+  ImageResourceContent* image = cachedImage();
   if (!image)
     return FloatSize();
 
@@ -794,7 +794,7 @@
 
   // Icky special case for deferred images:
   // A deferred image is not loading, does have pending activity, does not
-  // have an error, but it does have an ImageResource associated
+  // have an error, but it does have an ImageResourceContent associated
   // with it, so imageHasLoaded will be true even though the image hasn't
   // actually loaded. Fixing the definition of imageHasLoaded isn't
   // sufficient, because a deferred image does have pending activity, does not
@@ -802,8 +802,8 @@
   // was correct, imageStillLoading would become wrong.
   //
   // Instead of dealing with that, there's a separate check that the
-  // ImageResource has non-null image data associated with it, which isn't
-  // folded into imageHasLoaded above.
+  // ImageResourceContent has non-null image data associated with it, which
+  // isn't folded into imageHasLoaded above.
   if ((imageHasLoaded && imageHasImage) || imageStillLoading || imageIsDocument)
     ensurePrimaryContent();
   else
@@ -899,7 +899,7 @@
 }
 
 IntSize HTMLImageElement::bitmapSourceSize() const {
-  ImageResource* image = cachedImage();
+  ImageResourceContent* image = cachedImage();
   if (!image)
     return IntSize();
   LayoutSize lSize = image->imageSize(
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.h b/third_party/WebKit/Source/core/html/HTMLImageElement.h
index 0191492..372bac8 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.h
@@ -76,8 +76,11 @@
 
   String altText() const final;
 
-  ImageResource* cachedImage() const { return imageLoader().image(); }
-  void setImageResource(ImageResource* i) { imageLoader().setImage(i); }
+  ImageResourceContent* cachedImage() const { return imageLoader().image(); }
+  ImageResource* cachedImageResourceForImageDocument() const {
+    return imageLoader().imageResourceForImageDocument();
+  }
+  void setImageResource(ImageResourceContent* i) { imageLoader().setImage(i); }
 
   void setLoadingImageDocument() { imageLoader().setLoadingImageDocument(); }
 
diff --git a/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp b/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp
index a09e764..f7e5795 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp
@@ -9,7 +9,6 @@
 #include "core/dom/ElementRareData.h"
 #include "core/dom/Text.h"
 #include "core/dom/shadow/ShadowRoot.h"
-#include "core/fetch/ImageResource.h"
 #include "core/html/HTMLDivElement.h"
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLImageElement.h"
diff --git a/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp b/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
index ec64186..4db49d3 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
@@ -24,7 +24,7 @@
 #include "core/HTMLNames.h"
 #include "core/dom/Element.h"
 #include "core/events/Event.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ResourceLoadingLog.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLInputElement.h"
@@ -68,8 +68,8 @@
     toHTMLInputElement(element())->ensureFallbackContent();
 }
 
-void HTMLImageLoader::imageNotifyFinished(ImageResource*) {
-  ImageResource* cachedImage = image();
+void HTMLImageLoader::imageNotifyFinished(ImageResourceContent*) {
+  ImageResourceContent* cachedImage = image();
   Element* element = this->element();
   ImageLoader::imageNotifyFinished(cachedImage);
 
diff --git a/third_party/WebKit/Source/core/html/HTMLImageLoader.h b/third_party/WebKit/Source/core/html/HTMLImageLoader.h
index 31ca3f3..4b1a3d07 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageLoader.h
+++ b/third_party/WebKit/Source/core/html/HTMLImageLoader.h
@@ -37,7 +37,7 @@
 
   void dispatchLoadEvent() override;
 
-  void imageNotifyFinished(ImageResource*) override;
+  void imageNotifyFinished(ImageResourceContent*) override;
   String debugName() const override { return "HTMLImageLoader"; }
 
  private:
diff --git a/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp b/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
index 4239f69..9b3667d 100644
--- a/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
@@ -32,7 +32,6 @@
 #include "core/dom/TagCollection.h"
 #include "core/dom/Text.h"
 #include "core/dom/shadow/ShadowRoot.h"
-#include "core/fetch/ImageResource.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLImageLoader.h"
diff --git a/third_party/WebKit/Source/core/html/ImageDocument.cpp b/third_party/WebKit/Source/core/html/ImageDocument.cpp
index 8485eec..072b068 100644
--- a/third_party/WebKit/Source/core/html/ImageDocument.cpp
+++ b/third_party/WebKit/Source/core/html/ImageDocument.cpp
@@ -148,12 +148,13 @@
           !settings || settings->imagesEnabled(), document()->url()))
     return;
 
-  if (document()->cachedImage()) {
+  if (document()->cachedImageResourceDeprecated()) {
     RELEASE_ASSERT(length <= std::numeric_limits<unsigned>::max());
     // If decoding has already failed, there's no point in sending additional
     // data to the ImageResource.
-    if (document()->cachedImage()->getStatus() != Resource::DecodeError)
-      document()->cachedImage()->appendData(data, length);
+    if (document()->cachedImageResourceDeprecated()->getStatus() !=
+        Resource::DecodeError)
+      document()->cachedImageResourceDeprecated()->appendData(data, length);
   }
 
   if (!isDetached())
@@ -161,8 +162,10 @@
 }
 
 void ImageDocumentParser::finish() {
-  if (!isStopped() && document()->imageElement() && document()->cachedImage()) {
-    ImageResource* cachedImage = document()->cachedImage();
+  if (!isStopped() && document()->imageElement() &&
+      document()->cachedImageResourceDeprecated()) {
+    // TODO(hiroshige): Use ImageResourceContent instead of ImageResource.
+    ImageResource* cachedImage = document()->cachedImageResourceDeprecated();
     DocumentLoader* loader = document()->loader();
     cachedImage->setResponse(loader->response());
     cachedImage->finish(loader->timing().responseEnd());
@@ -264,9 +267,10 @@
   m_imageElement->setLoadingImageDocument();
   m_imageElement->setSrc(url().getString());
   body->appendChild(m_imageElement.get());
-  if (loader() && m_imageElement->cachedImage())
-    m_imageElement->cachedImage()->responseReceived(loader()->response(),
-                                                    nullptr);
+  if (loader() && m_imageElement->cachedImageResourceForImageDocument()) {
+    m_imageElement->cachedImageResourceForImageDocument()->responseReceived(
+        loader()->response(), nullptr);
+  }
 
   if (shouldShrinkToFit()) {
     // Add event listeners
@@ -565,7 +569,7 @@
   }
 }
 
-ImageResource* ImageDocument::cachedImage() {
+ImageResourceContent* ImageDocument::cachedImage() {
   if (!m_imageElement) {
     createDocumentStructure();
     if (isStopped()) {
@@ -577,6 +581,18 @@
   return m_imageElement->cachedImage();
 }
 
+ImageResource* ImageDocument::cachedImageResourceDeprecated() {
+  if (!m_imageElement) {
+    createDocumentStructure();
+    if (isStopped()) {
+      m_imageElement = nullptr;
+      return nullptr;
+    }
+  }
+
+  return m_imageElement->cachedImageResourceForImageDocument();
+}
+
 bool ImageDocument::shouldShrinkToFit() const {
   return frame()->isMainFrame();
 }
diff --git a/third_party/WebKit/Source/core/html/ImageDocument.h b/third_party/WebKit/Source/core/html/ImageDocument.h
index c47b53a..c391bdc 100644
--- a/third_party/WebKit/Source/core/html/ImageDocument.h
+++ b/third_party/WebKit/Source/core/html/ImageDocument.h
@@ -41,7 +41,11 @@
     return new ImageDocument(initializer);
   }
 
-  ImageResource* cachedImage();
+  ImageResourceContent* cachedImage();
+
+  // TODO(hiroshige): Remove this.
+  ImageResource* cachedImageResourceDeprecated();
+
   HTMLImageElement* imageElement() const { return m_imageElement.get(); }
 
   void windowSizeChanged();
diff --git a/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp b/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
index 10c711a..2f424dbf 100644
--- a/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
+++ b/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
@@ -27,7 +27,6 @@
 #include "core/InputTypeNames.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/events/MouseEvent.h"
-#include "core/fetch/ImageResource.h"
 #include "core/html/FormData.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/HTMLImageFallbackHelper.h"
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 78205de..14529c4 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -51,7 +51,7 @@
 #include "core/events/TextEvent.h"
 #include "core/events/TouchEvent.h"
 #include "core/events/WheelEvent.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/Deprecation.h"
 #include "core/frame/EventHandlerRegistry.h"
 #include "core/frame/FrameHost.h"
@@ -425,7 +425,7 @@
       StyleImage* styleImage = (*cursors)[i].image();
       if (!styleImage)
         continue;
-      ImageResource* cachedImage = styleImage->cachedImage();
+      ImageResourceContent* cachedImage = styleImage->cachedImage();
       if (!cachedImage)
         continue;
       float scale = styleImage->imageScaleFactor();
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
index 5fd511ea..7280fb3 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
@@ -36,7 +36,6 @@
 #include "core/HTMLNames.h"
 #include "core/dom/DOMImplementation.h"
 #include "core/dom/Document.h"
-#include "core/fetch/ImageResource.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/fetch/Resource.h"
 #include "core/fetch/ResourceFetcher.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
index f9b80b6..1a4e6864 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
@@ -898,7 +898,7 @@
     const LayoutImage& layoutImage) {
   std::unique_ptr<TracedValue> value = TracedValue::create();
   setGeneratingNodeInfo(value.get(), &layoutImage, "nodeId");
-  if (const ImageResource* resource = layoutImage.cachedImage())
+  if (const ImageResourceContent* resource = layoutImage.cachedImage())
     value->setString("url", resource->url().getString());
   return value;
 }
@@ -908,14 +908,14 @@
     const StyleImage& styleImage) {
   std::unique_ptr<TracedValue> value = TracedValue::create();
   setGeneratingNodeInfo(value.get(), &owningLayoutObject, "nodeId");
-  if (const ImageResource* resource = styleImage.cachedImage())
+  if (const ImageResourceContent* resource = styleImage.cachedImage())
     value->setString("url", resource->url().getString());
   return value;
 }
 
 std::unique_ptr<TracedValue> InspectorPaintImageEvent::data(
     const LayoutObject* owningLayoutObject,
-    const ImageResource& imageResource) {
+    const ImageResourceContent& imageResource) {
   std::unique_ptr<TracedValue> value = TracedValue::create();
   setGeneratingNodeInfo(value.get(), owningLayoutObject, "nodeId");
   value->setString("url", imageResource.url().getString());
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
index 7b1ff128..a48bcc32 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
@@ -37,7 +37,7 @@
 class HitTestLocation;
 class HitTestRequest;
 class HitTestResult;
-class ImageResource;
+class ImageResourceContent;
 class InvalidationSet;
 class PaintLayer;
 class LayoutRect;
@@ -293,7 +293,8 @@
 namespace InspectorPaintImageEvent {
 std::unique_ptr<TracedValue> data(const LayoutImage&);
 std::unique_ptr<TracedValue> data(const LayoutObject&, const StyleImage&);
-std::unique_ptr<TracedValue> data(const LayoutObject*, const ImageResource&);
+std::unique_ptr<TracedValue> data(const LayoutObject*,
+                                  const ImageResourceContent&);
 }
 
 namespace InspectorCommitLoadEvent {
diff --git a/third_party/WebKit/Source/core/layout/LayoutImage.cpp b/third_party/WebKit/Source/core/layout/LayoutImage.cpp
index 85d2499..e2a9ce30 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImage.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutImage.cpp
@@ -29,7 +29,7 @@
 #include "core/layout/LayoutImage.h"
 
 #include "core/HTMLNames.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/UseCounter.h"
@@ -178,7 +178,7 @@
   contentChanged(ImageChanged);
 }
 
-void LayoutImage::imageNotifyFinished(ImageResource* newImage) {
+void LayoutImage::imageNotifyFinished(ImageResourceContent* newImage) {
   if (!m_imageResource)
     return;
 
@@ -321,7 +321,7 @@
   if (!m_imageResource)
     return nullptr;
 
-  ImageResource* cachedImage = m_imageResource->cachedImage();
+  ImageResourceContent* cachedImage = m_imageResource->cachedImage();
   if (cachedImage && cachedImage->getImage() &&
       cachedImage->getImage()->isSVGImage())
     return toSVGImage(cachedImage->getImage())->embeddedReplacedContent();
diff --git a/third_party/WebKit/Source/core/layout/LayoutImage.h b/third_party/WebKit/Source/core/layout/LayoutImage.h
index 6a92201..668c8799 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImage.h
+++ b/third_party/WebKit/Source/core/layout/LayoutImage.h
@@ -62,7 +62,7 @@
   const LayoutImageResource* imageResource() const {
     return m_imageResource.get();
   }
-  ImageResource* cachedImage() const {
+  ImageResourceContent* cachedImage() const {
     return m_imageResource ? m_imageResource->cachedImage() : 0;
   }
 
@@ -117,7 +117,7 @@
 
   LayoutUnit minimumReplacedHeight() const override;
 
-  void imageNotifyFinished(ImageResource*) final;
+  void imageNotifyFinished(ImageResourceContent*) final;
   bool nodeAtPoint(HitTestResult&,
                    const HitTestLocation& locationInContainer,
                    const LayoutPoint& accumulatedOffset,
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp b/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp
index aaed687..a4b9b923 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp
@@ -53,7 +53,7 @@
   m_cachedImage->removeObserver(m_layoutObject);
 }
 
-void LayoutImageResource::setImageResource(ImageResource* newImage) {
+void LayoutImageResource::setImageResource(ImageResourceContent* newImage) {
   ASSERT(m_layoutObject);
 
   if (m_cachedImage == newImage)
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResource.h b/third_party/WebKit/Source/core/layout/LayoutImageResource.h
index ccf528b..2e6e102 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImageResource.h
+++ b/third_party/WebKit/Source/core/layout/LayoutImageResource.h
@@ -27,7 +27,7 @@
 #ifndef LayoutImageResource_h
 #define LayoutImageResource_h
 
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/style/StyleImage.h"
 
 namespace blink {
@@ -46,8 +46,8 @@
   virtual void initialize(LayoutObject*);
   virtual void shutdown();
 
-  void setImageResource(ImageResource*);
-  ImageResource* cachedImage() const { return m_cachedImage.get(); }
+  void setImageResource(ImageResourceContent*);
+  ImageResourceContent* cachedImage() const { return m_cachedImage.get(); }
   virtual bool hasImage() const { return m_cachedImage; }
 
   void resetAnimation();
@@ -71,7 +71,7 @@
  protected:
   LayoutImageResource();
   LayoutObject* m_layoutObject;
-  Member<ImageResource> m_cachedImage;
+  Member<ImageResourceContent> m_cachedImage;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.cpp b/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.cpp
index 00f91b6..3af832f6 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutImageResourceStyleImage.cpp
@@ -28,7 +28,6 @@
 
 #include "core/layout/LayoutImageResourceStyleImage.h"
 
-#include "core/fetch/ImageResource.h"
 #include "core/layout/LayoutReplaced.h"
 #include "core/style/StyleFetchedImage.h"
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp b/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp
index 934d02d..46ce9025 100644
--- a/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp
@@ -25,7 +25,6 @@
 
 #include "core/layout/LayoutListMarker.h"
 
-#include "core/fetch/ImageResource.h"
 #include "core/layout/LayoutAnalyzer.h"
 #include "core/layout/LayoutListItem.h"
 #include "core/layout/ListMarkerText.h"
diff --git a/third_party/WebKit/Source/core/layout/LayoutMenuList.cpp b/third_party/WebKit/Source/core/layout/LayoutMenuList.cpp
index c97fa74..868764f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMenuList.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMenuList.cpp
@@ -28,6 +28,7 @@
 
 #include "core/dom/AXObjectCache.h"
 #include "core/dom/NodeComputedStyle.h"
+#include "core/frame/FrameView.h"
 #include "core/html/HTMLOptionElement.h"
 #include "core/html/HTMLSelectElement.h"
 #include "core/layout/LayoutText.h"
@@ -98,8 +99,9 @@
 
   Length paddingStart =
       Length(LayoutTheme::theme().popupInternalPaddingStart(styleRef()), Fixed);
-  Length paddingEnd =
-      Length(LayoutTheme::theme().popupInternalPaddingEnd(styleRef()), Fixed);
+  Length paddingEnd = Length(LayoutTheme::theme().popupInternalPaddingEnd(
+                                 frameView()->getHostWindow(), styleRef()),
+                             Fixed);
   innerStyle.setPaddingLeft(styleRef().direction() == LTR ? paddingStart
                                                           : paddingEnd);
   innerStyle.setPaddingRight(styleRef().direction() == LTR ? paddingEnd
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index 49d84c95..fa98e5a 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -3145,7 +3145,8 @@
   return layoutObject->node()->isInert();
 }
 
-void LayoutObject::imageChanged(ImageResource* image, const IntRect* rect) {
+void LayoutObject::imageChanged(ImageResourceContent* image,
+                                const IntRect* rect) {
   ASSERT(m_node);
 
   // Image change notifications should not be received during paint because
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h
index 1482ace..467bf0a4 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -1446,7 +1446,7 @@
   virtual int caretMaxOffset() const;
 
   // ImageResourceClient override.
-  void imageChanged(ImageResource*, const IntRect* = nullptr) final;
+  void imageChanged(ImageResourceContent*, const IntRect* = nullptr) final;
   bool willRenderImage() final;
   bool getImageAnimationPolicy(ImageAnimationPolicy&) final;
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
index 03d700d..c814ba3 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
@@ -27,7 +27,6 @@
 #include "core/layout/LayoutTableRow.h"
 
 #include "core/HTMLNames.h"
-#include "core/fetch/ImageResource.h"
 #include "core/layout/HitTestResult.h"
 #include "core/layout/LayoutAnalyzer.h"
 #include "core/layout/LayoutState.h"
diff --git a/third_party/WebKit/Source/core/layout/LayoutTheme.h b/third_party/WebKit/Source/core/layout/LayoutTheme.h
index 8342271..598e5a8 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTheme.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTheme.h
@@ -41,6 +41,7 @@
 class ComputedStyle;
 class Element;
 class FileList;
+class HostWindow;
 class HTMLInputElement;
 class LayoutObject;
 class Theme;
@@ -167,7 +168,10 @@
   virtual int popupInternalPaddingStart(const ComputedStyle&) const {
     return 0;
   }
-  virtual int popupInternalPaddingEnd(const ComputedStyle&) const { return 0; }
+  virtual int popupInternalPaddingEnd(const HostWindow*,
+                                      const ComputedStyle&) const {
+    return 0;
+  }
   virtual int popupInternalPaddingTop(const ComputedStyle&) const { return 0; }
   virtual int popupInternalPaddingBottom(const ComputedStyle&) const {
     return 0;
diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp b/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp
index e880c74..a23b70c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutThemeDefault.cpp
@@ -28,6 +28,7 @@
 #include "core/layout/LayoutThemeFontProvider.h"
 #include "core/paint/MediaControlsPainter.h"
 #include "core/style/ComputedStyle.h"
+#include "platform/HostWindow.h"
 #include "platform/LayoutTestSupport.h"
 #include "platform/PlatformResourceLoader.h"
 #include "platform/graphics/Color.h"
@@ -42,7 +43,6 @@
 static const float defaultCancelButtonSize = 9;
 static const float minCancelButtonSize = 5;
 static const float maxCancelButtonSize = 21;
-static const int menuListArrowPaddingSize = 14;
 
 static bool useMockTheme() {
   return LayoutTestSupport::isMockThemeEnabledForTest();
@@ -55,7 +55,8 @@
 
 double LayoutThemeDefault::m_caretBlinkInterval;
 
-LayoutThemeDefault::LayoutThemeDefault() : LayoutTheme(nullptr) {
+LayoutThemeDefault::LayoutThemeDefault()
+    : LayoutTheme(nullptr), m_painter(*this) {
   m_caretBlinkInterval = LayoutTheme::caretBlinkInterval();
 }
 
@@ -316,8 +317,12 @@
 }
 
 int LayoutThemeDefault::popupInternalPaddingEnd(
+    const HostWindow* host,
     const ComputedStyle& style) const {
-  return menuListInternalPadding(style, 4 + menuListArrowPaddingSize);
+  if (style.appearance() == NoControlPart)
+    return 0;
+  return 1 * style.effectiveZoom() +
+         clampedMenuListArrowPaddingSize(host, style);
 }
 
 int LayoutThemeDefault::popupInternalPaddingTop(
@@ -331,6 +336,32 @@
 }
 
 // static
+int LayoutThemeDefault::scrollbarThicknessInDIP() {
+  int width = Platform::current()
+                  ->themeEngine()
+                  ->getSize(WebThemeEngine::PartScrollbarDownArrow)
+                  .width;
+  return width > 0 ? width : 15;
+}
+
+// static
+float LayoutThemeDefault::clampedMenuListArrowPaddingSize(
+    const HostWindow* host,
+    const ComputedStyle& style) {
+  int originalSize = scrollbarThicknessInDIP();
+  int scaledSize =
+      host ? host->windowToViewportScalar(originalSize) : originalSize;
+  // The result should not be samller than the scrollbar thickness in order to
+  // secure space for scrollbar in popup.
+  float deviceScale = 1.0f * scaledSize / originalSize;
+  if (style.effectiveZoom() < deviceScale)
+    return scaledSize;
+  // The value should be zoomed though scrollbars aren't scaled by zoom.
+  // crbug.com/432795.
+  return originalSize * style.effectiveZoom();
+}
+
+// static
 void LayoutThemeDefault::setDefaultFontSize(int fontSize) {
   LayoutThemeFontProvider::setDefaultFontSize(fontSize);
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeDefault.h b/third_party/WebKit/Source/core/layout/LayoutThemeDefault.h
index 9e15eb2..d88def7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutThemeDefault.h
+++ b/third_party/WebKit/Source/core/layout/LayoutThemeDefault.h
@@ -111,9 +111,13 @@
 
   // These methods define the padding for the MenuList's inner block.
   int popupInternalPaddingStart(const ComputedStyle&) const override;
-  int popupInternalPaddingEnd(const ComputedStyle&) const override;
+  int popupInternalPaddingEnd(const HostWindow*,
+                              const ComputedStyle&) const override;
   int popupInternalPaddingTop(const ComputedStyle&) const override;
   int popupInternalPaddingBottom(const ComputedStyle&) const override;
+  static int scrollbarThicknessInDIP();
+  static float clampedMenuListArrowPaddingSize(const HostWindow*,
+                                               const ComputedStyle&);
 
   // Provide a way to pass the default font size from the Settings object
   // to the layout theme. FIXME: http://b/1129186 A cleaner way would be
diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeMac.h b/third_party/WebKit/Source/core/layout/LayoutThemeMac.h
index 52d1750..587cafe 100644
--- a/third_party/WebKit/Source/core/layout/LayoutThemeMac.h
+++ b/third_party/WebKit/Source/core/layout/LayoutThemeMac.h
@@ -74,7 +74,8 @@
   int sliderTickOffsetFromTrackCenter() const override;
 
   int popupInternalPaddingStart(const ComputedStyle&) const override;
-  int popupInternalPaddingEnd(const ComputedStyle&) const override;
+  int popupInternalPaddingEnd(const HostWindow*,
+                              const ComputedStyle&) const override;
   int popupInternalPaddingTop(const ComputedStyle&) const override;
   int popupInternalPaddingBottom(const ComputedStyle&) const override;
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm b/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm
index 6522ad8..39fea2d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm
+++ b/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm
@@ -754,7 +754,8 @@
   return 0;
 }
 
-int LayoutThemeMac::popupInternalPaddingEnd(const ComputedStyle& style) const {
+int LayoutThemeMac::popupInternalPaddingEnd(const HostWindow*,
+                                            const ComputedStyle& style) const {
   if (style.appearance() == MenulistPart)
     return popupButtonPadding(
                controlSizeForFont(style))[ThemeMac::RightMargin] *
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index dfd8cac..d238b39 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -27,7 +27,7 @@
 
 #include "core/HTMLNames.h"
 #include "core/dom/DOMNodeIds.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/RemoteFrame.h"
@@ -2480,7 +2480,7 @@
       imageLayoutObject->hasObjectFit())
     return false;
 
-  if (ImageResource* cachedImage = imageLayoutObject->cachedImage()) {
+  if (ImageResourceContent* cachedImage = imageLayoutObject->cachedImage()) {
     if (!cachedImage->hasImage())
       return false;
 
@@ -2511,7 +2511,7 @@
   ASSERT(layoutObject()->isImage());
   LayoutImage* imageLayoutObject = toLayoutImage(layoutObject());
 
-  ImageResource* cachedImage = imageLayoutObject->cachedImage();
+  ImageResourceContent* cachedImage = imageLayoutObject->cachedImage();
   if (!cachedImage)
     return;
 
diff --git a/third_party/WebKit/Source/core/layout/shapes/Shape.cpp b/third_party/WebKit/Source/core/layout/shapes/Shape.cpp
index 364fe581..6316ee8 100644
--- a/third_party/WebKit/Source/core/layout/shapes/Shape.cpp
+++ b/third_party/WebKit/Source/core/layout/shapes/Shape.cpp
@@ -32,7 +32,6 @@
 #include "core/css/BasicShapeFunctions.h"
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/DOMTypedArray.h"
-#include "core/fetch/ImageResource.h"
 #include "core/layout/shapes/BoxShape.h"
 #include "core/layout/shapes/PolygonShape.h"
 #include "core/layout/shapes/RasterShape.h"
diff --git a/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp b/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp
index a758f9b..1a4fa4a 100644
--- a/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp
+++ b/third_party/WebKit/Source/core/layout/shapes/ShapeOutsideInfo.cpp
@@ -98,7 +98,7 @@
     return true;
 
   ASSERT(styleImage.cachedImage());
-  ImageResource& imageResource = *(styleImage.cachedImage());
+  ImageResourceContent& imageResource = *(styleImage.cachedImage());
   if (imageResource.isAccessAllowed(document.getSecurityOrigin()))
     return true;
 
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGImage.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGImage.cpp
index 90b10140..1bce9cf7 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGImage.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGImage.cpp
@@ -68,7 +68,7 @@
 }
 
 FloatSize LayoutSVGImage::calculateObjectSize() const {
-  ImageResource* cachedImage = m_imageResource->cachedImage();
+  ImageResourceContent* cachedImage = m_imageResource->cachedImage();
   if (!cachedImage || cachedImage->errorOccurred())
     return m_objectBoundingBox.size();
 
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
index fcd86324..8dab86f 100644
--- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
@@ -182,10 +182,11 @@
 
 DEFINE_TRACE(ImageLoader) {
   visitor->trace(m_image);
+  visitor->trace(m_imageResourceForImageDocument);
   visitor->trace(m_element);
 }
 
-void ImageLoader::setImage(ImageResource* newImage) {
+void ImageLoader::setImage(ImageResourceContent* newImage) {
   setImageWithoutConsideringPendingLoadEvent(newImage);
 
   // Only consider updating the protection ref-count of the Element immediately
@@ -195,9 +196,9 @@
 }
 
 void ImageLoader::setImageWithoutConsideringPendingLoadEvent(
-    ImageResource* newImage) {
+    ImageResourceContent* newImage) {
   DCHECK(m_failedLoadURL.isEmpty());
-  ImageResource* oldImage = m_image.get();
+  ImageResourceContent* oldImage = m_image.get();
   if (newImage != oldImage) {
     m_image = newImage;
     if (m_hasPendingLoadEvent) {
@@ -289,7 +290,7 @@
     return;
 
   AtomicString imageSourceURL = m_element->imageSourceURL();
-  ImageResource* newImage = nullptr;
+  ImageResourceContent* newImage = nullptr;
   if (!url.isNull()) {
     // Unlike raw <img>, we block mixed content inside of <picture> or
     // <img srcset>.
@@ -319,7 +320,7 @@
       request.setAllowImagePlaceholder();
     }
 
-    newImage = ImageResource::fetch(request, document.fetcher());
+    newImage = ImageResourceContent::fetch(request, document.fetcher());
 
     if (!newImage && !pageIsBeingDismissed(&document)) {
       crossSiteOrCSPViolationOccurred(imageSourceURL);
@@ -335,7 +336,7 @@
     noImageResourceToLoad();
   }
 
-  ImageResource* oldImage = m_image.get();
+  ImageResourceContent* oldImage = m_image.get();
   if (updateBehavior == UpdateSizeChanged && m_element->layoutObject() &&
       m_element->layoutObject()->isImage() && newImage == oldImage) {
     toLayoutImage(m_element->layoutObject())->intrinsicSizeChanged();
@@ -398,9 +399,11 @@
   // funneling the main resource bytes into m_image, so just create an
   // ImageResource to be populated later.
   if (m_loadingImageDocument && updateBehavior != UpdateForcedReload) {
-    setImage(
-        ImageResource::create(imageSourceToKURL(m_element->imageSourceURL())));
-    m_image->setStatus(Resource::Pending);
+    ImageResource* imageResource =
+        ImageResource::create(imageSourceToKURL(m_element->imageSourceURL()));
+    imageResource->setStatus(Resource::Pending);
+    m_imageResourceForImageDocument = imageResource;
+    setImage(imageResource->getContent());
     return;
   }
 
@@ -420,7 +423,7 @@
   // Allow the idiom "img.src=''; img.src='.." to clear down the image before an
   // asynchronous load completes.
   if (imageSourceURL.isEmpty()) {
-    ImageResource* image = m_image.get();
+    ImageResourceContent* image = m_image.get();
     if (image) {
       image->removeObserver(this);
     }
@@ -468,7 +471,7 @@
           url.protocolIsData());
 }
 
-void ImageLoader::imageNotifyFinished(ImageResource* resource) {
+void ImageLoader::imageNotifyFinished(ImageResourceContent* resource) {
   RESOURCE_LOADING_DVLOG(1)
       << "ImageLoader::imageNotifyFinished " << this
       << "; m_hasPendingLoadEvent=" << m_hasPendingLoadEvent;
@@ -511,7 +514,6 @@
     updatedHasPendingEvent();
     return;
   }
-  DCHECK(!resource->wasCanceled());
   loadEventSender().dispatchEventSoon(this);
 }
 
@@ -545,7 +547,7 @@
   // Only update the layoutObject if it doesn't have an image or if what we have
   // is a complete image.  This prevents flickering in the case where a dynamic
   // change is happening between two images.
-  ImageResource* cachedImage = imageResource->cachedImage();
+  ImageResourceContent* cachedImage = imageResource->cachedImage();
   if (m_image != cachedImage && (m_imageComplete || !cachedImage))
     imageResource->setImageResource(m_image.get());
 }
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.h b/third_party/WebKit/Source/core/loader/ImageLoader.h
index f37edbc9..5db73d0 100644
--- a/third_party/WebKit/Source/core/loader/ImageLoader.h
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.h
@@ -25,6 +25,7 @@
 
 #include "core/CoreExport.h"
 #include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ImageResourceObserver.h"
 #include "platform/heap/Handle.h"
 #include "wtf/HashSet.h"
@@ -81,9 +82,12 @@
   Element* element() const { return m_element; }
   bool imageComplete() const { return m_imageComplete && !m_pendingTask; }
 
-  ImageResource* image() const { return m_image.get(); }
+  ImageResourceContent* image() const { return m_image.get(); }
+  ImageResource* imageResourceForImageDocument() const {
+    return m_imageResourceForImageDocument;
+  }
   // Cancels pending load events, and doesn't dispatch new ones.
-  void setImage(ImageResource*);
+  void setImage(ImageResourceContent*);
 
   bool isLoadingImageDocument() { return m_loadingImageDocument; }
   void setLoadingImageDocument() { m_loadingImageDocument = true; }
@@ -104,7 +108,7 @@
   bool getImageAnimationPolicy(ImageAnimationPolicy&) final;
 
  protected:
-  void imageNotifyFinished(ImageResource*) override;
+  void imageNotifyFinished(ImageResourceContent*) override;
 
  private:
   class Task;
@@ -126,7 +130,7 @@
   LayoutImageResource* layoutImageResource();
   void updateLayoutObject();
 
-  void setImageWithoutConsideringPendingLoadEvent(ImageResource*);
+  void setImageWithoutConsideringPendingLoadEvent(ImageResourceContent*);
   void clearFailedLoadURL();
   void dispatchErrorEvent();
   void crossSiteOrCSPViolationOccurred(AtomicString);
@@ -148,7 +152,8 @@
   void dispose();
 
   Member<Element> m_element;
-  Member<ImageResource> m_image;
+  Member<ImageResourceContent> m_image;
+  Member<ImageResource> m_imageResourceForImageDocument;
   // FIXME: Oilpan: We might be able to remove this Persistent hack when
   // ImageResourceClient is traceable.
   GC_PLUGIN_IGNORE("http://crbug.com/383741")
diff --git a/third_party/WebKit/Source/core/loader/ProgressTrackerTest.cpp b/third_party/WebKit/Source/core/loader/ProgressTrackerTest.cpp
index b1c5095..af9bfe4 100644
--- a/third_party/WebKit/Source/core/loader/ProgressTrackerTest.cpp
+++ b/third_party/WebKit/Source/core/loader/ProgressTrackerTest.cpp
@@ -7,6 +7,7 @@
 #include "core/frame/Settings.h"
 #include "core/loader/EmptyClients.h"
 #include "core/testing/DummyPageHolder.h"
+#include "platform/network/ResourceResponse.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResourceTest.cpp b/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResourceTest.cpp
index 4dc929f..cfd86a6 100644
--- a/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResourceTest.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/CSSStyleSheetResourceTest.cpp
@@ -19,6 +19,7 @@
 #include "core/fetch/FetchContext.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
 #include "core/fetch/FetchRequest.h"
+#include "core/fetch/ImageResource.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/testing/DummyPageHolder.h"
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index 8a439f750..ef4d262 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -46,7 +46,7 @@
 #include "core/editing/commands/DragAndDropCommand.h"
 #include "core/editing/serializers/Serialization.h"
 #include "core/events/TextEvent.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
@@ -829,7 +829,7 @@
   return node;
 }
 
-static ImageResource* getImageResource(Element* element) {
+static ImageResourceContent* getImageResource(Element* element) {
   DCHECK(element);
   LayoutObject* layoutObject = element->layoutObject();
   if (!layoutObject || !layoutObject->isImage())
@@ -840,7 +840,7 @@
 
 static Image* getImage(Element* element) {
   DCHECK(element);
-  ImageResource* cachedImage = getImageResource(element);
+  ImageResourceContent* cachedImage = getImageResource(element);
   return (cachedImage && !cachedImage->errorOccurred())
              ? cachedImage->getImage()
              : nullptr;
diff --git a/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp b/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp
index d68dec20..b4519adc 100644
--- a/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp
@@ -92,7 +92,8 @@
           ->align() != SVGPreserveAspectRatio::kSvgPreserveaspectratioNone)
     return m_layoutSVGImage.objectBoundingBox().size();
 
-  ImageResource* cachedImage = m_layoutSVGImage.imageResource()->cachedImage();
+  ImageResourceContent* cachedImage =
+      m_layoutSVGImage.imageResource()->cachedImage();
 
   // Images with preserveAspectRatio=none should force non-uniform scaling. This
   // can be achieved by setting the image's container size to its viewport size
diff --git a/third_party/WebKit/Source/core/paint/ThemePainterDefault.cpp b/third_party/WebKit/Source/core/paint/ThemePainterDefault.cpp
index 0b0fb12..1ce8c7c 100644
--- a/third_party/WebKit/Source/core/paint/ThemePainterDefault.cpp
+++ b/third_party/WebKit/Source/core/paint/ThemePainterDefault.cpp
@@ -24,9 +24,10 @@
 
 #include "core/paint/ThemePainterDefault.h"
 
+#include "core/frame/FrameView.h"
 #include "core/layout/LayoutObject.h"
 #include "core/layout/LayoutProgress.h"
-#include "core/layout/LayoutTheme.h"
+#include "core/layout/LayoutThemeDefault.h"
 #include "core/paint/MediaControlsPainter.h"
 #include "core/paint/PaintInfo.h"
 #include "platform/LayoutTestSupport.h"
@@ -42,10 +43,6 @@
 namespace {
 
 const unsigned defaultButtonBackgroundColor = 0xffdddddd;
-const unsigned mockDropdownMenuListArrowPadding = 3;
-// This is equal to the padding provided by the LayoutMenuList which is
-// calculated based on |menuListArrowPaddingSize| in LayoutThemeDefault.
-const unsigned mockDropdownMenuListArrowWidth = 18;
 
 bool useMockTheme() {
   return LayoutTestSupport::isMockThemeEnabledForTest();
@@ -142,7 +139,8 @@
 
 }  // namespace
 
-ThemePainterDefault::ThemePainterDefault() : ThemePainter() {}
+ThemePainterDefault::ThemePainterDefault(LayoutThemeDefault& theme)
+    : ThemePainter(), m_theme(theme) {}
 
 bool ThemePainterDefault::paintCheckbox(const LayoutObject& o,
                                         const PaintInfo& i,
@@ -285,34 +283,40 @@
     const LayoutBox& box,
     const IntRect& rect,
     WebThemeEngine::ExtraParams& extraParams) {
-  const int right = rect.x() + rect.width();
+  const int left = rect.x() + box.borderLeft();
+  const int right = rect.x() + rect.width() - box.borderRight();
   const int middle = rect.y() + rect.height() / 2;
 
   extraParams.menuList.arrowY = middle;
+  float arrowBoxWidth = m_theme.clampedMenuListArrowPaddingSize(
+      box.frameView()->getHostWindow(), box.styleRef());
+  float arrowScaleFactor = arrowBoxWidth / m_theme.scrollbarThicknessInDIP();
   if (useMockTheme()) {
     // The size and position of the drop-down button is different between
     // the mock theme and the regular aura theme.
-    int extraPadding =
-        mockDropdownMenuListArrowPadding * box.styleRef().effectiveZoom();
-    int arrowBoxWidth =
-        mockDropdownMenuListArrowWidth * box.styleRef().effectiveZoom();
-    int arrowSize = std::min(arrowBoxWidth, rect.height()) - 2 * extraPadding;
+
+    // Padding inside the arrowBox.
+    float extraPadding = 2 * arrowScaleFactor;
+    float arrowSize =
+        std::min(arrowBoxWidth,
+                 static_cast<float>(rect.height() - box.borderTop() -
+                                    box.borderBottom())) -
+        2 * extraPadding;
+    // |arrowX| is the middle position for mock theme engine.
     extraParams.menuList.arrowX =
         (box.styleRef().direction() == RTL)
             ? rect.x() + extraPadding + (arrowSize / 2)
             : right - (arrowSize / 2) - extraPadding;
     extraParams.menuList.arrowSize = arrowSize;
   } else {
-    const int arrowSize = 6;
-    const int arrowPadding = 6;
-    extraParams.menuList.arrowX =
-        (box.styleRef().direction() == RTL)
-            ? rect.x() + arrowPadding * box.styleRef().effectiveZoom() +
-                  box.borderLeft()
-            : right -
-                  (arrowSize + arrowPadding) * box.styleRef().effectiveZoom() -
-                  box.borderRight();
-    extraParams.menuList.arrowSize = arrowSize * box.styleRef().effectiveZoom();
+    // TODO(tkent): This should be 7.0 to match scroll bar buttons.
+    float arrowSize = 6.0 * arrowScaleFactor;
+    // Put the 6px arrow at the center of paddingForArrow area.
+    // |arrowX| is the left position for Aura theme engine.
+    extraParams.menuList.arrowX = (box.styleRef().direction() == RTL)
+                                      ? left + (arrowBoxWidth - arrowSize) / 2
+                                      : right - (arrowBoxWidth + arrowSize) / 2;
+    extraParams.menuList.arrowSize = arrowSize;
   }
   extraParams.menuList.arrowColor = box.resolveColor(CSSPropertyColor).rgb();
 }
diff --git a/third_party/WebKit/Source/core/paint/ThemePainterDefault.h b/third_party/WebKit/Source/core/paint/ThemePainterDefault.h
index 48c2190..a66dd69 100644
--- a/third_party/WebKit/Source/core/paint/ThemePainterDefault.h
+++ b/third_party/WebKit/Source/core/paint/ThemePainterDefault.h
@@ -35,10 +35,11 @@
 namespace blink {
 
 class LayoutBox;
+class LayoutThemeDefault;
 
 class ThemePainterDefault final : public ThemePainter {
  public:
-  ThemePainterDefault();
+  explicit ThemePainterDefault(LayoutThemeDefault&);
 
  private:
   bool paintCheckbox(const LayoutObject&,
@@ -84,6 +85,9 @@
   void setupMenuListArrow(const LayoutBox&,
                           const IntRect&,
                           WebThemeEngine::ExtraParams&);
+
+  // ThemePaintDefault is a part object of m_theme.
+  LayoutThemeDefault& m_theme;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/style/ShapeValue.h b/third_party/WebKit/Source/core/style/ShapeValue.h
index 17db4222..86f785263 100644
--- a/third_party/WebKit/Source/core/style/ShapeValue.h
+++ b/third_party/WebKit/Source/core/style/ShapeValue.h
@@ -30,7 +30,7 @@
 #ifndef ShapeValue_h
 #define ShapeValue_h
 
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/style/BasicShapes.h"
 #include "core/style/DataEquivalency.h"
 #include "core/style/ComputedStyleConstants.h"
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
index cb70d27a..501e1c5a 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
@@ -24,14 +24,14 @@
 #include "core/style/StyleFetchedImage.h"
 
 #include "core/css/CSSImageValue.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/layout/LayoutObject.h"
 #include "core/svg/graphics/SVGImage.h"
 #include "core/svg/graphics/SVGImageForContainer.h"
 
 namespace blink {
 
-StyleFetchedImage::StyleFetchedImage(ImageResource* image,
+StyleFetchedImage::StyleFetchedImage(ImageResourceContent* image,
                                      const Document& document,
                                      const KURL& url)
     : m_image(image), m_document(&document), m_url(url) {
@@ -54,7 +54,7 @@
   return m_image.get();
 }
 
-ImageResource* StyleFetchedImage::cachedImage() const {
+ImageResourceContent* StyleFetchedImage::cachedImage() const {
   return m_image.get();
 }
 
@@ -110,7 +110,7 @@
   m_image->removeObserver(layoutObject);
 }
 
-void StyleFetchedImage::imageNotifyFinished(ImageResource*) {
+void StyleFetchedImage::imageNotifyFinished(ImageResourceContent*) {
   if (m_document && m_image && m_image->getImage() &&
       m_image->getImage()->isSVGImage())
     toSVGImage(m_image->getImage())->updateUseCounters(*m_document);
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImage.h b/third_party/WebKit/Source/core/style/StyleFetchedImage.h
index 63ca01e..07bb8bb 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImage.h
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImage.h
@@ -31,14 +31,13 @@
 namespace blink {
 
 class Document;
-class ImageResource;
 
 class StyleFetchedImage final : public StyleImage,
                                 public ImageResourceObserver {
   USING_PRE_FINALIZER(StyleFetchedImage, dispose);
 
  public:
-  static StyleFetchedImage* create(ImageResource* image,
+  static StyleFetchedImage* create(ImageResourceContent* image,
                                    const Document& document,
                                    const KURL& url) {
     return new StyleFetchedImage(image, document, url);
@@ -60,22 +59,22 @@
   bool usesImageContainerSize() const override;
   void addClient(LayoutObject*) override;
   void removeClient(LayoutObject*) override;
-  void imageNotifyFinished(ImageResource*) override;
+  void imageNotifyFinished(ImageResourceContent*) override;
   String debugName() const override { return "StyleFetchedImage"; }
   PassRefPtr<Image> image(const LayoutObject&,
                           const IntSize&,
                           float zoom) const override;
   bool knownToBeOpaque(const LayoutObject&) const override;
-  ImageResource* cachedImage() const override;
+  ImageResourceContent* cachedImage() const override;
 
   DECLARE_VIRTUAL_TRACE();
 
  private:
-  StyleFetchedImage(ImageResource*, const Document&, const KURL&);
+  StyleFetchedImage(ImageResourceContent*, const Document&, const KURL&);
 
   void dispose();
 
-  Member<ImageResource> m_image;
+  Member<ImageResourceContent> m_image;
   Member<const Document> m_document;
   const KURL m_url;
 };
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
index 27ffd46c..dd6d73d 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
@@ -26,13 +26,13 @@
 #include "core/style/StyleFetchedImageSet.h"
 
 #include "core/css/CSSImageSetValue.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/layout/LayoutObject.h"
 #include "core/svg/graphics/SVGImageForContainer.h"
 
 namespace blink {
 
-StyleFetchedImageSet::StyleFetchedImageSet(ImageResource* image,
+StyleFetchedImageSet::StyleFetchedImageSet(ImageResourceContent* image,
                                            float imageScaleFactor,
                                            CSSImageSetValue* value,
                                            const KURL& url)
@@ -56,7 +56,7 @@
   return m_bestFitImage.get();
 }
 
-ImageResource* StyleFetchedImageSet::cachedImage() const {
+ImageResourceContent* StyleFetchedImageSet::cachedImage() const {
   return m_bestFitImage.get();
 }
 
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h
index 0ed7ee36..6d04c60 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.h
@@ -33,7 +33,6 @@
 
 namespace blink {
 
-class ImageResource;
 class CSSImageSetValue;
 
 // This class keeps one cached image and has access to a set of alternatives.
@@ -43,7 +42,7 @@
   USING_PRE_FINALIZER(StyleFetchedImageSet, dispose);
 
  public:
-  static StyleFetchedImageSet* create(ImageResource* image,
+  static StyleFetchedImageSet* create(ImageResourceContent* image,
                                       float imageScaleFactor,
                                       CSSImageSetValue* value,
                                       const KURL& url) {
@@ -74,12 +73,12 @@
                           float) const override;
   float imageScaleFactor() const override { return m_imageScaleFactor; }
   bool knownToBeOpaque(const LayoutObject&) const override;
-  ImageResource* cachedImage() const override;
+  ImageResourceContent* cachedImage() const override;
 
   DECLARE_VIRTUAL_TRACE();
 
  private:
-  StyleFetchedImageSet(ImageResource*,
+  StyleFetchedImageSet(ImageResourceContent*,
                        float imageScaleFactor,
                        CSSImageSetValue*,
                        const KURL&);
@@ -88,7 +87,7 @@
 
   String debugName() const override { return "StyleFetchedImageSet"; }
 
-  Member<ImageResource> m_bestFitImage;
+  Member<ImageResourceContent> m_bestFitImage;
   float m_imageScaleFactor;
 
   Member<CSSImageSetValue> m_imageSetValue;  // Not retained; it owns us.
diff --git a/third_party/WebKit/Source/core/style/StyleImage.h b/third_party/WebKit/Source/core/style/StyleImage.h
index 1e425c7..ffb1218b 100644
--- a/third_party/WebKit/Source/core/style/StyleImage.h
+++ b/third_party/WebKit/Source/core/style/StyleImage.h
@@ -31,7 +31,7 @@
 namespace blink {
 
 class CSSValue;
-class ImageResource;
+class ImageResourceContent;
 class IntSize;
 class LayoutObject;
 class LayoutSize;
@@ -72,7 +72,7 @@
   virtual WrappedImagePtr data() const = 0;
   virtual float imageScaleFactor() const { return 1; }
   virtual bool knownToBeOpaque(const LayoutObject&) const = 0;
-  virtual ImageResource* cachedImage() const { return 0; }
+  virtual ImageResourceContent* cachedImage() const { return 0; }
 
   ALWAYS_INLINE bool isImageResource() const { return m_isImageResource; }
   ALWAYS_INLINE bool isPendingImage() const { return m_isPendingImage; }
diff --git a/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp
index d17687e..88659473 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp
@@ -75,7 +75,7 @@
 void SVGFEImageElement::fetchImageResource() {
   FetchRequest request(
       ResourceRequest(ownerDocument()->completeURL(hrefString())), localName());
-  m_cachedImage = ImageResource::fetch(request, document().fetcher());
+  m_cachedImage = ImageResourceContent::fetch(request, document().fetcher());
 
   if (m_cachedImage)
     m_cachedImage->addObserver(this);
@@ -135,7 +135,7 @@
     clearResourceReferences();
 }
 
-void SVGFEImageElement::imageNotifyFinished(ImageResource*) {
+void SVGFEImageElement::imageNotifyFinished(ImageResourceContent*) {
   if (!isConnected())
     return;
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFEImageElement.h b/third_party/WebKit/Source/core/svg/SVGFEImageElement.h
index d668c1d..ba01823d 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEImageElement.h
+++ b/third_party/WebKit/Source/core/svg/SVGFEImageElement.h
@@ -22,7 +22,7 @@
 #define SVGFEImageElement_h
 
 #include "core/SVGNames.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/fetch/ImageResourceObserver.h"
 #include "core/svg/SVGAnimatedPreserveAspectRatio.h"
 #include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
@@ -55,7 +55,7 @@
   explicit SVGFEImageElement(Document&);
 
   void svgAttributeChanged(const QualifiedName&) override;
-  void imageNotifyFinished(ImageResource*) override;
+  void imageNotifyFinished(ImageResourceContent*) override;
   String debugName() const override { return "SVGFEImageElement"; }
 
   FilterEffect* build(SVGFilterBuilder*, Filter*) override;
@@ -69,7 +69,7 @@
 
   Member<SVGAnimatedPreserveAspectRatio> m_preserveAspectRatio;
 
-  Member<ImageResource> m_cachedImage;
+  Member<ImageResourceContent> m_cachedImage;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/svg/SVGImageElement.h b/third_party/WebKit/Source/core/svg/SVGImageElement.h
index 663b72b..54db5f4 100644
--- a/third_party/WebKit/Source/core/svg/SVGImageElement.h
+++ b/third_party/WebKit/Source/core/svg/SVGImageElement.h
@@ -51,7 +51,7 @@
   }
 
   // Exposed for testing.
-  ImageResource* cachedImage() const { return imageLoader().image(); }
+  ImageResourceContent* cachedImage() const { return imageLoader().image(); }
 
  private:
   explicit SVGImageElement(Document&);
diff --git a/third_party/WebKit/Source/core/svg/SVGImageLoader.cpp b/third_party/WebKit/Source/core/svg/SVGImageLoader.cpp
index 3a24aa3..cc0b1c7 100644
--- a/third_party/WebKit/Source/core/svg/SVGImageLoader.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGImageLoader.cpp
@@ -21,7 +21,6 @@
 #include "core/svg/SVGImageLoader.h"
 
 #include "core/events/Event.h"
-#include "core/fetch/ImageResource.h"
 #include "core/svg/SVGImageElement.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
index 768f101..c80b14d 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -490,8 +490,9 @@
   ScriptForbiddenScope forbidScript;
 
   // The calls below may trigger GCs, so set up the required persistent
-  // reference on the ImageResource which owns this SVGImage. By transitivity,
-  // that will keep the associated SVGImageChromeClient object alive.
+  // reference on the ImageResourceContent which owns this SVGImage. By
+  // transitivity, that will keep the associated SVGImageChromeClient object
+  // alive.
   Persistent<ImageObserver> protect(getImageObserver());
   m_page->animator().serviceScriptedAnimations(monotonicAnimationStartTime);
   // Do *not* update the paint phase. It's critical to paint only when
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
index 8bb8d20..d9bffe4 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
@@ -112,7 +112,7 @@
     return;
 
   // The SVGImageChromeClient object's lifetime is dependent on
-  // the ImageObserver (an ImageResource) of its image. Should it
+  // the ImageObserver (an ImageResourceContent) of its image. Should it
   // be dead and about to be lazily swept out, do not proceed.
   //
   // TODO(Oilpan): move (SVG)Image to the Oilpan heap, and avoid
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index 7a121fc..3c842d1 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -583,7 +583,7 @@
     return;
   }
 
-  ImageResource* resource = nullptr;
+  ImageResourceContent* resource = nullptr;
   if (isHTMLImageElement(*image)) {
     resource = toHTMLImageElement(*image).cachedImage();
   } else if (isSVGImageElement(*image)) {
@@ -614,7 +614,7 @@
                                       ExceptionState& exceptionState) {
   ASSERT(image);
 
-  ImageResource* resource = nullptr;
+  ImageResourceContent* resource = nullptr;
   if (isHTMLImageElement(*image)) {
     resource = toHTMLImageElement(*image).cachedImage();
   } else if (isSVGImageElement(*image)) {
diff --git a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp
index 52c1d831..a846f2b 100644
--- a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp
+++ b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp
@@ -7,7 +7,7 @@
 #include "core/dom/DOMException.h"
 #include "core/dom/DOMRect.h"
 #include "core/dom/Document.h"
-#include "core/fetch/ImageResource.h"
+#include "core/fetch/ImageResourceContent.h"
 #include "core/frame/ImageBitmap.h"
 #include "core/frame/LocalFrame.h"
 #include "core/html/HTMLImageElement.h"
@@ -151,7 +151,7 @@
     return promise;
   }
 
-  ImageResource* const imageResource = img->cachedImage();
+  ImageResourceContent* const imageResource = img->cachedImage();
   if (!imageResource || imageResource->errorOccurred()) {
     resolver->reject(DOMException::create(
         InvalidStateError, "Failed to load or decode HTMLImageElement."));
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index 3ba9722d..e9d8b80c 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -34,7 +34,6 @@
 #include "core/dom/DOMArrayBuffer.h"
 #include "core/dom/DOMTypedArray.h"
 #include "core/dom/FlexibleArrayBufferView.h"
-#include "core/fetch/ImageResource.h"
 #include "core/frame/ImageBitmap.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
index d5570f31..93a1e92 100644
--- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
+++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
@@ -205,7 +205,8 @@
     return SizeAvailable;
 
   // If ImageSource::setData() fails, we know that this is a decode error.
-  // Report size available so that it gets registered as such in ImageResource.
+  // Report size available so that it gets registered as such in
+  // ImageResourceContent.
   if (!m_source.setData(std::move(data), allDataReceived))
     return SizeAvailable;
 
diff --git a/third_party/WebKit/Source/platform/graphics/Image.h b/third_party/WebKit/Source/platform/graphics/Image.h
index f6819a70..e238844 100644
--- a/third_party/WebKit/Source/platform/graphics/Image.h
+++ b/third_party/WebKit/Source/platform/graphics/Image.h
@@ -140,7 +140,7 @@
   // animation update for CSS and advance the SMIL timeline by one frame.
   virtual void advanceAnimationForTesting() {}
 
-  // Typically the ImageResource that owns us.
+  // Typically the ImageResourceContent that owns us.
   ImageObserver* getImageObserver() const {
     return m_imageObserverDisabled ? nullptr : m_imageObserver;
   }
@@ -218,8 +218,8 @@
   // TODO(Oilpan): consider having Image on the Oilpan heap and
   // turn this into a Member<>.
   //
-  // The observer (an ImageResource) is an untraced member, with the
-  // ImageResource being responsible for clearing itself out.
+  // The observer (an ImageResourceContent) is an untraced member, with the
+  // ImageResourceContent being responsible for clearing itself out.
   UntracedMember<ImageObserver> m_imageObserver;
   bool m_imageObserverDisabled;
 };
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.h b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
index aa577f1..2eb8b1e1 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.h
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
@@ -108,6 +108,9 @@
   bool enabled() const override { return m_enabled; }
   void setEnabled(bool) override;
 
+  // This returns device-scale-factor-aware pixel value.
+  // e.g. 15 in dsf=1.0, 30 in dsf=2.0.
+  // See also ScrolbarTheme::scrollbatThickness().
   int scrollbarThickness() const;
 
   // Called by the ScrollableArea when the scroll offset changes.
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.h b/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.h
index a56f215..ec03635 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarTheme.h
@@ -58,6 +58,8 @@
 
   virtual ScrollbarPart hitTest(const ScrollbarThemeClient&, const IntPoint&);
 
+  // This returns a fixed value regardless of device-scale-factor.
+  // See also Scrollbar::scrollbarThickness().
   virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar) {
     return 0;
   }
diff --git a/third_party/WebKit/Source/web/WebFrameSerializer.cpp b/third_party/WebKit/Source/web/WebFrameSerializer.cpp
index a6765b7..1cec65c8 100644
--- a/third_party/WebKit/Source/web/WebFrameSerializer.cpp
+++ b/third_party/WebKit/Source/web/WebFrameSerializer.cpp
@@ -84,7 +84,8 @@
   bool shouldIgnoreAttribute(const Element&, const Attribute&) override;
   bool rewriteLink(const Element&, String& rewrittenLink) override;
   bool shouldSkipResourceWithURL(const KURL&) override;
-  bool shouldSkipResource(const Resource&) override;
+  bool shouldSkipResource(
+      FrameSerializer::ResourceHasCacheControlNoStoreHeader) override;
   Vector<Attribute> getCustomAttributes(const Element&) override;
 
  private:
@@ -160,11 +161,13 @@
 }
 
 bool MHTMLFrameSerializerDelegate::shouldSkipResource(
-    const Resource& resource) {
+    FrameSerializer::ResourceHasCacheControlNoStoreHeader
+        hasCacheControlNoStoreHeader) {
   return m_webDelegate.cacheControlPolicy() ==
              WebFrameSerializerCacheControlPolicy::
                  SkipAnyFrameOrResourceMarkedNoStore &&
-         resource.hasCacheControlNoStoreHeader();
+         hasCacheControlNoStoreHeader ==
+             FrameSerializer::HasCacheControlNoStoreHeader;
 }
 
 Vector<Attribute> MHTMLFrameSerializerDelegate::getCustomAttributes(
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index 4b2e879..018aea3 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -10055,7 +10055,7 @@
   EXPECT_TRUE(document->isImageDocument());
 
   ImageDocument* imgDocument = toImageDocument(document);
-  ImageResource* resource = imgDocument->cachedImage();
+  ImageResource* resource = imgDocument->cachedImageResourceDeprecated();
 
   EXPECT_TRUE(resource);
   EXPECT_NE(0, resource->loadFinishTime());
diff --git a/tools/perf/benchmarks/v8_browsing.py b/tools/perf/benchmarks/v8_browsing.py
index bdf9445..4e4c15f 100644
--- a/tools/perf/benchmarks/v8_browsing.py
+++ b/tools/perf/benchmarks/v8_browsing.py
@@ -105,7 +105,6 @@
     return possible_browser.platform.GetDeviceTypeName() == 'Desktop'
 
 
-@benchmark.Disabled('win')  # http://crbug.com/654209
 class V8DesktopBrowsingBenchmark(_V8DesktopBrowsingBenchmark):
   PLATFORM = 'desktop'
   TEST_SUFFIX = ''
@@ -117,7 +116,6 @@
   TEST_SUFFIX = ''
 
 
-@benchmark.Disabled('win')  # http://crbug.com/654209
 class V8DesktopIgnitionBrowsingBenchmark(_V8DesktopBrowsingBenchmark):
   PLATFORM = 'desktop'
   TEST_SUFFIX = '_ignition'
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py
index 27ce50e..83364b66 100644
--- a/tools/perf/page_sets/system_health/browsing_stories.py
+++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -176,7 +176,6 @@
   SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
 
 
-@decorators.Disabled('mac')  # crbug.com/662959
 class RedditDesktopStory(_NewsBrowsingStory):
   """The top website in http://www.alexa.com/topsites/category/News"""
   NAME = 'browse:news:reddit'